mcp-remote 0.1.13 → 0.1.15

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.
@@ -10301,7 +10301,7 @@ var z = /* @__PURE__ */ Object.freeze({
10301
10301
  ZodError
10302
10302
  });
10303
10303
 
10304
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.12.1/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
10304
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
10305
10305
  var LATEST_PROTOCOL_VERSION = "2025-03-26";
10306
10306
  var SUPPORTED_PROTOCOL_VERSIONS = [
10307
10307
  LATEST_PROTOCOL_VERSION,
@@ -11126,7 +11126,7 @@ var McpError = class extends Error {
11126
11126
  }
11127
11127
  };
11128
11128
 
11129
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.12.1/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
11129
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
11130
11130
  var DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
11131
11131
  var Protocol = class {
11132
11132
  constructor(_options) {
@@ -11472,7 +11472,7 @@ function mergeCapabilities(base, additional) {
11472
11472
  }, { ...base });
11473
11473
  }
11474
11474
 
11475
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.12.1/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js
11475
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js
11476
11476
  var import_ajv = __toESM(require_ajv(), 1);
11477
11477
  var Client = class extends Protocol {
11478
11478
  /**
@@ -11707,7 +11707,7 @@ var Client = class extends Protocol {
11707
11707
  };
11708
11708
 
11709
11709
  // package.json
11710
- var version = "0.1.13";
11710
+ var version = "0.1.15";
11711
11711
 
11712
11712
  // node_modules/.pnpm/pkce-challenge@5.0.0/node_modules/pkce-challenge/dist/index.node.js
11713
11713
  var crypto;
@@ -11748,7 +11748,7 @@ async function pkceChallenge(length) {
11748
11748
  };
11749
11749
  }
11750
11750
 
11751
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.12.1/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.js
11751
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.js
11752
11752
  var OAuthProtectedResourceMetadataSchema = z.object({
11753
11753
  resource: z.string().url(),
11754
11754
  authorization_servers: z.array(z.string().url()).optional(),
@@ -11830,13 +11830,130 @@ var OAuthTokenRevocationRequestSchema = z.object({
11830
11830
  token_type_hint: z.string().optional()
11831
11831
  }).strip();
11832
11832
 
11833
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.12.1/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js
11833
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/errors.js
11834
+ var OAuthError = class extends Error {
11835
+ constructor(message, errorUri) {
11836
+ super(message);
11837
+ this.errorUri = errorUri;
11838
+ this.errorCode = this.constructor.errorCode;
11839
+ this.name = this.constructor.name;
11840
+ }
11841
+ /**
11842
+ * Converts the error to a standard OAuth error response object
11843
+ */
11844
+ toResponseObject() {
11845
+ const response = {
11846
+ error: this.errorCode,
11847
+ error_description: this.message
11848
+ };
11849
+ if (this.errorUri) {
11850
+ response.error_uri = this.errorUri;
11851
+ }
11852
+ return response;
11853
+ }
11854
+ };
11855
+ var InvalidRequestError = class extends OAuthError {
11856
+ };
11857
+ InvalidRequestError.errorCode = "invalid_request";
11858
+ var InvalidClientError = class extends OAuthError {
11859
+ };
11860
+ InvalidClientError.errorCode = "invalid_client";
11861
+ var InvalidGrantError = class extends OAuthError {
11862
+ };
11863
+ InvalidGrantError.errorCode = "invalid_grant";
11864
+ var UnauthorizedClientError = class extends OAuthError {
11865
+ };
11866
+ UnauthorizedClientError.errorCode = "unauthorized_client";
11867
+ var UnsupportedGrantTypeError = class extends OAuthError {
11868
+ };
11869
+ UnsupportedGrantTypeError.errorCode = "unsupported_grant_type";
11870
+ var InvalidScopeError = class extends OAuthError {
11871
+ };
11872
+ InvalidScopeError.errorCode = "invalid_scope";
11873
+ var AccessDeniedError = class extends OAuthError {
11874
+ };
11875
+ AccessDeniedError.errorCode = "access_denied";
11876
+ var ServerError = class extends OAuthError {
11877
+ };
11878
+ ServerError.errorCode = "server_error";
11879
+ var TemporarilyUnavailableError = class extends OAuthError {
11880
+ };
11881
+ TemporarilyUnavailableError.errorCode = "temporarily_unavailable";
11882
+ var UnsupportedResponseTypeError = class extends OAuthError {
11883
+ };
11884
+ UnsupportedResponseTypeError.errorCode = "unsupported_response_type";
11885
+ var UnsupportedTokenTypeError = class extends OAuthError {
11886
+ };
11887
+ UnsupportedTokenTypeError.errorCode = "unsupported_token_type";
11888
+ var InvalidTokenError = class extends OAuthError {
11889
+ };
11890
+ InvalidTokenError.errorCode = "invalid_token";
11891
+ var MethodNotAllowedError = class extends OAuthError {
11892
+ };
11893
+ MethodNotAllowedError.errorCode = "method_not_allowed";
11894
+ var TooManyRequestsError = class extends OAuthError {
11895
+ };
11896
+ TooManyRequestsError.errorCode = "too_many_requests";
11897
+ var InvalidClientMetadataError = class extends OAuthError {
11898
+ };
11899
+ InvalidClientMetadataError.errorCode = "invalid_client_metadata";
11900
+ var InsufficientScopeError = class extends OAuthError {
11901
+ };
11902
+ InsufficientScopeError.errorCode = "insufficient_scope";
11903
+ var OAUTH_ERRORS = {
11904
+ [InvalidRequestError.errorCode]: InvalidRequestError,
11905
+ [InvalidClientError.errorCode]: InvalidClientError,
11906
+ [InvalidGrantError.errorCode]: InvalidGrantError,
11907
+ [UnauthorizedClientError.errorCode]: UnauthorizedClientError,
11908
+ [UnsupportedGrantTypeError.errorCode]: UnsupportedGrantTypeError,
11909
+ [InvalidScopeError.errorCode]: InvalidScopeError,
11910
+ [AccessDeniedError.errorCode]: AccessDeniedError,
11911
+ [ServerError.errorCode]: ServerError,
11912
+ [TemporarilyUnavailableError.errorCode]: TemporarilyUnavailableError,
11913
+ [UnsupportedResponseTypeError.errorCode]: UnsupportedResponseTypeError,
11914
+ [UnsupportedTokenTypeError.errorCode]: UnsupportedTokenTypeError,
11915
+ [InvalidTokenError.errorCode]: InvalidTokenError,
11916
+ [MethodNotAllowedError.errorCode]: MethodNotAllowedError,
11917
+ [TooManyRequestsError.errorCode]: TooManyRequestsError,
11918
+ [InvalidClientMetadataError.errorCode]: InvalidClientMetadataError,
11919
+ [InsufficientScopeError.errorCode]: InsufficientScopeError
11920
+ };
11921
+
11922
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js
11834
11923
  var UnauthorizedError = class extends Error {
11835
11924
  constructor(message) {
11836
11925
  super(message !== null && message !== void 0 ? message : "Unauthorized");
11837
11926
  }
11838
11927
  };
11839
- async function auth(provider, { serverUrl, authorizationCode, scope, resourceMetadataUrl }) {
11928
+ async function parseErrorResponse(input) {
11929
+ const statusCode = input instanceof Response ? input.status : void 0;
11930
+ const body = input instanceof Response ? await input.text() : input;
11931
+ try {
11932
+ const result = OAuthErrorResponseSchema.parse(JSON.parse(body));
11933
+ const { error, error_description, error_uri } = result;
11934
+ const errorClass = OAUTH_ERRORS[error] || ServerError;
11935
+ return new errorClass(error_description || "", error_uri);
11936
+ } catch (error) {
11937
+ const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}Invalid OAuth error response: ${error}. Raw body: ${body}`;
11938
+ return new ServerError(errorMessage);
11939
+ }
11940
+ }
11941
+ async function auth(provider, options) {
11942
+ var _a, _b;
11943
+ try {
11944
+ return await authInternal(provider, options);
11945
+ } catch (error) {
11946
+ if (error instanceof InvalidClientError || error instanceof UnauthorizedClientError) {
11947
+ await ((_a = provider.invalidateCredentials) === null || _a === void 0 ? void 0 : _a.call(provider, "all"));
11948
+ return await authInternal(provider, options);
11949
+ } else if (error instanceof InvalidGrantError) {
11950
+ await ((_b = provider.invalidateCredentials) === null || _b === void 0 ? void 0 : _b.call(provider, "tokens"));
11951
+ return await authInternal(provider, options);
11952
+ }
11953
+ throw error;
11954
+ }
11955
+ }
11956
+ async function authInternal(provider, { serverUrl, authorizationCode, scope, resourceMetadataUrl }) {
11840
11957
  let authorizationServerUrl = serverUrl;
11841
11958
  try {
11842
11959
  const resourceMetadata = await discoverOAuthProtectedResourceMetadata(resourceMetadataUrl || serverUrl);
@@ -11885,7 +12002,12 @@ async function auth(provider, { serverUrl, authorizationCode, scope, resourceMet
11885
12002
  await provider.saveTokens(newTokens);
11886
12003
  return "AUTHORIZED";
11887
12004
  } catch (error) {
11888
- console.error("Could not refresh OAuth tokens:", error);
12005
+ if (!(error instanceof OAuthError) || error instanceof ServerError) {
12006
+ console.error("Could not refresh OAuth tokens:", error);
12007
+ } else {
12008
+ console.warn(`OAuth token refresh failed: ${JSON.stringify(error.toResponseObject())}`);
12009
+ throw error;
12010
+ }
11889
12011
  }
11890
12012
  }
11891
12013
  const state = provider.state ? await provider.state() : void 0;
@@ -12037,7 +12159,7 @@ async function exchangeAuthorization(authorizationServerUrl, { metadata, clientI
12037
12159
  body: params
12038
12160
  });
12039
12161
  if (!response.ok) {
12040
- throw new Error(`Token exchange failed: HTTP ${response.status}`);
12162
+ throw await parseErrorResponse(response);
12041
12163
  }
12042
12164
  return OAuthTokensSchema.parse(await response.json());
12043
12165
  }
@@ -12068,7 +12190,7 @@ async function refreshAuthorization(authorizationServerUrl, { metadata, clientIn
12068
12190
  body: params
12069
12191
  });
12070
12192
  if (!response.ok) {
12071
- throw new Error(`Token refresh failed: HTTP ${response.status}`);
12193
+ throw await parseErrorResponse(response);
12072
12194
  }
12073
12195
  return OAuthTokensSchema.parse({ refresh_token: refreshToken, ...await response.json() });
12074
12196
  }
@@ -12090,7 +12212,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
12090
12212
  body: JSON.stringify(clientMetadata)
12091
12213
  });
12092
12214
  if (!response.ok) {
12093
- throw new Error(`Dynamic client registration failed: HTTP ${response.status}`);
12215
+ throw await parseErrorResponse(response);
12094
12216
  }
12095
12217
  return OAuthClientInformationFullSchema.parse(await response.json());
12096
12218
  }
@@ -12495,7 +12617,7 @@ function getBaseURL() {
12495
12617
  return doc && typeof doc == "object" && "baseURI" in doc && typeof doc.baseURI == "string" ? doc.baseURI : void 0;
12496
12618
  }
12497
12619
 
12498
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.12.1/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js
12620
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js
12499
12621
  var SseError = class extends Error {
12500
12622
  constructor(code, message, event) {
12501
12623
  super(`SSE error: ${message}`);
@@ -12678,7 +12800,7 @@ var EventSourceParserStream = class extends TransformStream {
12678
12800
  }
12679
12801
  };
12680
12802
 
12681
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.12.1/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js
12803
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js
12682
12804
  var DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS = {
12683
12805
  initialReconnectionDelay: 1e3,
12684
12806
  maxReconnectionDelay: 3e4,
@@ -13082,9 +13204,9 @@ async function writeTextFile(serverUrlHash, filename, text) {
13082
13204
  import express from "express";
13083
13205
  import net from "net";
13084
13206
  import crypto2 from "crypto";
13085
- import fs2, { readFile } from "fs/promises";
13207
+ import fs2 from "fs";
13208
+ import { readFile, rm } from "fs/promises";
13086
13209
  import path2 from "path";
13087
- import os2 from "os";
13088
13210
  var REASON_AUTH_NEEDED = "authentication-needed";
13089
13211
  var REASON_TRANSPORT_FALLBACK = "falling-back-to-alternate-transport";
13090
13212
  var pid = process.pid;
@@ -13093,7 +13215,7 @@ function getTimestamp() {
13093
13215
  const now = /* @__PURE__ */ new Date();
13094
13216
  return now.toISOString();
13095
13217
  }
13096
- async function debugLog(message, ...args) {
13218
+ function debugLog(message, ...args) {
13097
13219
  if (!DEBUG) return;
13098
13220
  const serverUrlHash = global.currentServerUrlHash;
13099
13221
  if (!serverUrlHash) {
@@ -13103,12 +13225,12 @@ async function debugLog(message, ...args) {
13103
13225
  try {
13104
13226
  const formattedMessage = `[${getTimestamp()}][${pid}] ${message}`;
13105
13227
  console.error(formattedMessage, ...args);
13106
- const configDir = process.env.MCP_REMOTE_CONFIG_DIR || path2.join(os2.homedir(), ".mcp-auth");
13107
- await fs2.mkdir(configDir, { recursive: true });
13228
+ const configDir = getConfigDir();
13229
+ fs2.mkdirSync(configDir, { recursive: true });
13108
13230
  const logPath = path2.join(configDir, `${serverUrlHash}_debug.log`);
13109
13231
  const logMessage = `${formattedMessage} ${args.map((arg) => typeof arg === "object" ? JSON.stringify(arg) : String(arg)).join(" ")}
13110
13232
  `;
13111
- await fs2.appendFile(logPath, logMessage, { encoding: "utf8" });
13233
+ fs2.appendFileSync(logPath, logMessage, { encoding: "utf8" });
13112
13234
  } catch (error) {
13113
13235
  console.error(`[DEBUG LOG ERROR] ${error}`);
13114
13236
  }
@@ -13116,8 +13238,7 @@ async function debugLog(message, ...args) {
13116
13238
  function log(str, ...rest) {
13117
13239
  console.error(`[${pid}] ${str}`, ...rest);
13118
13240
  if (DEBUG && global.currentServerUrlHash) {
13119
- debugLog(str, ...rest).catch(() => {
13120
- });
13241
+ debugLog(str, ...rest);
13121
13242
  }
13122
13243
  }
13123
13244
  function mcpProxy({ transportToClient, transportToServer }) {
@@ -13131,7 +13252,6 @@ function mcpProxy({ transportToClient, transportToServer }) {
13131
13252
  method: message.method,
13132
13253
  id: message.id,
13133
13254
  params: message.params ? JSON.stringify(message.params).substring(0, 500) : void 0
13134
- }).catch(() => {
13135
13255
  });
13136
13256
  }
13137
13257
  if (message.method === "initialize") {
@@ -13139,8 +13259,7 @@ function mcpProxy({ transportToClient, transportToServer }) {
13139
13259
  if (clientInfo) clientInfo.name = `${clientInfo.name} (via mcp-remote ${version})`;
13140
13260
  log(JSON.stringify(message, null, 2));
13141
13261
  if (DEBUG) {
13142
- debugLog("Initialize message with modified client info", { clientInfo }).catch(() => {
13143
- });
13262
+ debugLog("Initialize message with modified client info", { clientInfo });
13144
13263
  }
13145
13264
  }
13146
13265
  transportToServer.send(message).catch(onServerError);
@@ -13154,7 +13273,6 @@ function mcpProxy({ transportToClient, transportToServer }) {
13154
13273
  id: message.id,
13155
13274
  result: message.result ? "result-present" : void 0,
13156
13275
  error: message.error
13157
- }).catch(() => {
13158
13276
  });
13159
13277
  }
13160
13278
  transportToClient.send(message).catch(onClientError);
@@ -13164,8 +13282,7 @@ function mcpProxy({ transportToClient, transportToServer }) {
13164
13282
  return;
13165
13283
  }
13166
13284
  transportToClientClosed = true;
13167
- if (DEBUG) debugLog("Local transport closed, closing remote transport").catch(() => {
13168
- });
13285
+ if (DEBUG) debugLog("Local transport closed, closing remote transport");
13169
13286
  transportToServer.close().catch(onServerError);
13170
13287
  };
13171
13288
  transportToServer.onclose = () => {
@@ -13173,21 +13290,18 @@ function mcpProxy({ transportToClient, transportToServer }) {
13173
13290
  return;
13174
13291
  }
13175
13292
  transportToServerClosed = true;
13176
- if (DEBUG) debugLog("Remote transport closed, closing local transport").catch(() => {
13177
- });
13293
+ if (DEBUG) debugLog("Remote transport closed, closing local transport");
13178
13294
  transportToClient.close().catch(onClientError);
13179
13295
  };
13180
13296
  transportToClient.onerror = onClientError;
13181
13297
  transportToServer.onerror = onServerError;
13182
13298
  function onClientError(error) {
13183
13299
  log("Error from local client:", error);
13184
- if (DEBUG) debugLog("Error from local client", { errorMessage: error.message, stack: error.stack }).catch(() => {
13185
- });
13300
+ if (DEBUG) debugLog("Error from local client", { stack: error.stack });
13186
13301
  }
13187
13302
  function onServerError(error) {
13188
13303
  log("Error from remote server:", error);
13189
- if (DEBUG) debugLog("Error from remote server", { errorMessage: error.message, stack: error.stack }).catch(() => {
13190
- });
13304
+ if (DEBUG) debugLog("Error from remote server", { stack: error.stack });
13191
13305
  }
13192
13306
  }
13193
13307
  async function connectToRemoteServer(client, serverUrl, authProvider, headers, authInitializer, transportStrategy = "http-first", recursionReasons = /* @__PURE__ */ new Set()) {
@@ -13220,22 +13334,21 @@ async function connectToRemoteServer(client, serverUrl, authProvider, headers, a
13220
13334
  requestInit: { headers }
13221
13335
  });
13222
13336
  try {
13223
- if (DEBUG) await debugLog("Attempting to connect to remote server", { sseTransport });
13337
+ if (DEBUG) debugLog("Attempting to connect to remote server", { sseTransport });
13224
13338
  if (client) {
13225
- if (DEBUG) await debugLog("Connecting client to transport");
13339
+ if (DEBUG) debugLog("Connecting client to transport");
13226
13340
  await client.connect(transport);
13227
13341
  } else {
13228
- if (DEBUG) await debugLog("Starting transport directly");
13342
+ if (DEBUG) debugLog("Starting transport directly");
13229
13343
  await transport.start();
13230
13344
  if (!sseTransport) {
13231
- if (DEBUG) await debugLog("Creating test transport for HTTP-only connection test");
13345
+ if (DEBUG) debugLog("Creating test transport for HTTP-only connection test");
13232
13346
  const testTransport = new StreamableHTTPClientTransport(url, { authProvider, requestInit: { headers } });
13233
13347
  const testClient = new Client({ name: "mcp-remote-fallback-test", version: "0.0.0" }, { capabilities: {} });
13234
13348
  await testClient.connect(testTransport);
13235
13349
  }
13236
13350
  }
13237
13351
  log(`Connected to remote server using ${transport.constructor.name}`);
13238
- if (DEBUG) await debugLog(`Connected to remote server successfully`, { transportType: transport.constructor.name });
13239
13352
  return transport;
13240
13353
  } catch (error) {
13241
13354
  if (error instanceof Error && shouldAttemptFallback && (error.message.includes("405") || error.message.includes("Method Not Allowed") || error.message.includes("404") || error.message.includes("Not Found"))) {
@@ -13259,47 +13372,52 @@ async function connectToRemoteServer(client, serverUrl, authProvider, headers, a
13259
13372
  } else if (error instanceof UnauthorizedError || error instanceof Error && error.message.includes("Unauthorized")) {
13260
13373
  log("Authentication required. Initializing auth...");
13261
13374
  if (DEBUG) {
13262
- await debugLog("Authentication required, initializing auth process", {
13375
+ debugLog("Authentication error detected", {
13376
+ errorCode: error instanceof OAuthError ? error.errorCode : void 0,
13263
13377
  errorMessage: error.message,
13264
13378
  stack: error.stack
13265
13379
  });
13266
13380
  }
13267
- if (DEBUG) await debugLog("Calling authInitializer to start auth flow");
13381
+ if (DEBUG) debugLog("Calling authInitializer to start auth flow");
13268
13382
  const { waitForAuthCode, skipBrowserAuth } = await authInitializer();
13269
13383
  if (skipBrowserAuth) {
13270
13384
  log("Authentication required but skipping browser auth - using shared auth");
13271
- if (DEBUG) await debugLog("Authentication required but skipping browser auth - using shared auth");
13272
13385
  } else {
13273
13386
  log("Authentication required. Waiting for authorization...");
13274
- if (DEBUG) await debugLog("Authentication required. Waiting for authorization...");
13275
13387
  }
13276
- if (DEBUG) await debugLog("Waiting for auth code from callback server");
13388
+ if (DEBUG) debugLog("Waiting for auth code from callback server");
13277
13389
  const code = await waitForAuthCode();
13278
- if (DEBUG) await debugLog("Received auth code from callback server");
13390
+ if (DEBUG) debugLog("Received auth code from callback server");
13279
13391
  try {
13280
13392
  log("Completing authorization...");
13281
- if (DEBUG) await debugLog("Completing authorization with transport.finishAuth");
13282
13393
  await transport.finishAuth(code);
13283
- if (DEBUG) await debugLog("Authorization completed successfully");
13394
+ if (DEBUG) debugLog("Authorization completed successfully");
13284
13395
  if (recursionReasons.has(REASON_AUTH_NEEDED)) {
13285
13396
  const errorMessage = `Already attempted reconnection for reason: ${REASON_AUTH_NEEDED}. Giving up.`;
13286
13397
  log(errorMessage);
13287
- if (DEBUG) await debugLog("Already attempted auth reconnection, giving up", { recursionReasons: Array.from(recursionReasons) });
13398
+ if (DEBUG)
13399
+ debugLog("Already attempted auth reconnection, giving up", {
13400
+ recursionReasons: Array.from(recursionReasons)
13401
+ });
13288
13402
  throw new Error(errorMessage);
13289
13403
  }
13290
13404
  recursionReasons.add(REASON_AUTH_NEEDED);
13291
13405
  log(`Recursively reconnecting for reason: ${REASON_AUTH_NEEDED}`);
13292
- if (DEBUG) await debugLog("Recursively reconnecting after auth", { recursionReasons: Array.from(recursionReasons) });
13406
+ if (DEBUG) debugLog("Recursively reconnecting after auth", { recursionReasons: Array.from(recursionReasons) });
13293
13407
  return connectToRemoteServer(client, serverUrl, authProvider, headers, authInitializer, transportStrategy, recursionReasons);
13294
13408
  } catch (authError) {
13295
13409
  log("Authorization error:", authError);
13296
- if (DEBUG) await debugLog("Authorization error during finishAuth", { errorMessage: authError.message, stack: authError.stack });
13410
+ if (DEBUG)
13411
+ debugLog("Authorization error during finishAuth", {
13412
+ errorMessage: authError.message,
13413
+ stack: authError.stack
13414
+ });
13297
13415
  throw authError;
13298
13416
  }
13299
13417
  } else {
13300
13418
  log("Connection error:", error);
13301
13419
  if (DEBUG)
13302
- await debugLog("Connection error", {
13420
+ debugLog("Connection error", {
13303
13421
  errorMessage: error.message,
13304
13422
  stack: error.stack,
13305
13423
  transportType: transport.constructor.name
@@ -13497,8 +13615,7 @@ async function parseCommandLineArgs(args, usage) {
13497
13615
  const serverUrlHash = getServerUrlHash(serverUrl);
13498
13616
  global.currentServerUrlHash = serverUrlHash;
13499
13617
  if (DEBUG) {
13500
- debugLog(`Starting mcp-remote with server URL: ${serverUrl}`).catch(() => {
13501
- });
13618
+ debugLog(`Starting mcp-remote with server URL: ${serverUrl}`);
13502
13619
  }
13503
13620
  const defaultPort = calculateDefaultPort(serverUrlHash);
13504
13621
  const [existingClientPort, availablePort] = await Promise.all([findExistingClientPort(serverUrlHash), findAvailablePort(defaultPort)]);
@@ -13508,7 +13625,7 @@ async function parseCommandLineArgs(args, usage) {
13508
13625
  log(
13509
13626
  `Warning! Specified callback port of ${specifiedPort}, which conflicts with existing client registration port ${existingClientPort}. Deleting existing client data to force reregistration.`
13510
13627
  );
13511
- await fs2.rm(getConfigFilePath(serverUrlHash, "client_info.json"));
13628
+ await rm(getConfigFilePath(serverUrlHash, "client_info.json"));
13512
13629
  }
13513
13630
  log(`Using specified callback port: ${specifiedPort}`);
13514
13631
  callbackPort = specifiedPort;
@@ -13552,6 +13669,26 @@ function setupSignalHandlers(cleanup) {
13552
13669
  function getServerUrlHash(serverUrl) {
13553
13670
  return crypto2.createHash("md5").update(serverUrl).digest("hex");
13554
13671
  }
13672
+ function sanitizeUrl(raw) {
13673
+ const abort = () => {
13674
+ throw new Error(`Invalid url to pass to open(): ${raw}`);
13675
+ };
13676
+ let url;
13677
+ try {
13678
+ url = new URL(raw);
13679
+ } catch (_) {
13680
+ abort();
13681
+ }
13682
+ if (url.protocol !== "https:" && url.protocol !== "http:") abort();
13683
+ if (url.hostname !== encodeURIComponent(url.hostname)) abort();
13684
+ url.pathname = url.pathname.slice(0, 1) + encodeURIComponent(url.pathname.slice(1)).replace(/%2f/ig, "/");
13685
+ url.search = url.search.slice(0, 1) + Array.from(url.searchParams.entries()).map(sanitizeParam).join("&");
13686
+ url.hash = url.hash.slice(0, 1) + encodeURIComponent(url.hash.slice(1));
13687
+ return url.href;
13688
+ }
13689
+ function sanitizeParam([k, v]) {
13690
+ return `${encodeURIComponent(k)}${v.length > 0 ? `=${encodeURIComponent(v)}` : ""}`;
13691
+ }
13555
13692
 
13556
13693
  // src/lib/node-oauth-client-provider.ts
13557
13694
  import open from "open";
@@ -13606,9 +13743,9 @@ var NodeOAuthClientProvider = class {
13606
13743
  * @returns The client information or undefined
13607
13744
  */
13608
13745
  async clientInformation() {
13609
- if (DEBUG) await debugLog(this.serverUrlHash, "Reading client info");
13746
+ if (DEBUG) debugLog("Reading client info");
13610
13747
  if (this.staticOAuthClientInfo) {
13611
- if (DEBUG) await debugLog(this.serverUrlHash, "Returning static client info");
13748
+ if (DEBUG) debugLog("Returning static client info");
13612
13749
  return this.staticOAuthClientInfo;
13613
13750
  }
13614
13751
  const clientInfo = await readJsonFile(
@@ -13616,7 +13753,7 @@ var NodeOAuthClientProvider = class {
13616
13753
  "client_info.json",
13617
13754
  OAuthClientInformationFullSchema
13618
13755
  );
13619
- if (DEBUG) await debugLog(this.serverUrlHash, "Client info result:", clientInfo ? "Found" : "Not found");
13756
+ if (DEBUG) debugLog("Client info result:", clientInfo ? "Found" : "Not found");
13620
13757
  return clientInfo;
13621
13758
  }
13622
13759
  /**
@@ -13624,7 +13761,7 @@ var NodeOAuthClientProvider = class {
13624
13761
  * @param clientInformation The client information to save
13625
13762
  */
13626
13763
  async saveClientInformation(clientInformation) {
13627
- if (DEBUG) await debugLog(this.serverUrlHash, "Saving client info", { client_id: clientInformation.client_id });
13764
+ if (DEBUG) debugLog("Saving client info", { client_id: clientInformation.client_id });
13628
13765
  await writeJsonFile(this.serverUrlHash, "client_info.json", clientInformation);
13629
13766
  }
13630
13767
  /**
@@ -13633,21 +13770,21 @@ var NodeOAuthClientProvider = class {
13633
13770
  */
13634
13771
  async tokens() {
13635
13772
  if (DEBUG) {
13636
- await debugLog(this.serverUrlHash, "Reading OAuth tokens");
13637
- await debugLog(this.serverUrlHash, "Token request stack trace:", new Error().stack);
13773
+ debugLog("Reading OAuth tokens");
13774
+ debugLog("Token request stack trace:", new Error().stack);
13638
13775
  }
13639
13776
  const tokens = await readJsonFile(this.serverUrlHash, "tokens.json", OAuthTokensSchema);
13640
13777
  if (DEBUG) {
13641
13778
  if (tokens) {
13642
13779
  const timeLeft = tokens.expires_in || 0;
13643
13780
  if (typeof tokens.expires_in !== "number" || tokens.expires_in < 0) {
13644
- await debugLog(this.serverUrlHash, "\u26A0\uFE0F WARNING: Invalid expires_in detected while reading tokens \u26A0\uFE0F", {
13781
+ debugLog("\u26A0\uFE0F WARNING: Invalid expires_in detected while reading tokens \u26A0\uFE0F", {
13645
13782
  expiresIn: tokens.expires_in,
13646
13783
  tokenObject: JSON.stringify(tokens),
13647
13784
  stack: new Error("Invalid expires_in value").stack
13648
13785
  });
13649
13786
  }
13650
- await debugLog(this.serverUrlHash, "Token result:", {
13787
+ debugLog("Token result:", {
13651
13788
  found: true,
13652
13789
  hasAccessToken: !!tokens.access_token,
13653
13790
  hasRefreshToken: !!tokens.refresh_token,
@@ -13656,7 +13793,7 @@ var NodeOAuthClientProvider = class {
13656
13793
  expiresInValue: tokens.expires_in
13657
13794
  });
13658
13795
  } else {
13659
- await debugLog(this.serverUrlHash, "Token result: Not found");
13796
+ debugLog("Token result: Not found");
13660
13797
  }
13661
13798
  }
13662
13799
  return tokens;
@@ -13669,13 +13806,13 @@ var NodeOAuthClientProvider = class {
13669
13806
  if (DEBUG) {
13670
13807
  const timeLeft = tokens.expires_in || 0;
13671
13808
  if (typeof tokens.expires_in !== "number" || tokens.expires_in < 0) {
13672
- await debugLog(this.serverUrlHash, "\u26A0\uFE0F WARNING: Invalid expires_in detected in tokens \u26A0\uFE0F", {
13809
+ debugLog("\u26A0\uFE0F WARNING: Invalid expires_in detected in tokens \u26A0\uFE0F", {
13673
13810
  expiresIn: tokens.expires_in,
13674
13811
  tokenObject: JSON.stringify(tokens),
13675
13812
  stack: new Error("Invalid expires_in value").stack
13676
13813
  });
13677
13814
  }
13678
- await debugLog(this.serverUrlHash, "Saving tokens", {
13815
+ debugLog("Saving tokens", {
13679
13816
  hasAccessToken: !!tokens.access_token,
13680
13817
  hasRefreshToken: !!tokens.refresh_token,
13681
13818
  expiresIn: `${timeLeft} seconds`,
@@ -13693,14 +13830,13 @@ var NodeOAuthClientProvider = class {
13693
13830
  Please authorize this client by visiting:
13694
13831
  ${authorizationUrl.toString()}
13695
13832
  `);
13696
- if (DEBUG) await debugLog(this.serverUrlHash, "Redirecting to authorization URL", authorizationUrl.toString());
13833
+ if (DEBUG) debugLog("Redirecting to authorization URL", authorizationUrl.toString());
13697
13834
  try {
13698
- await open(authorizationUrl.toString());
13835
+ await open(sanitizeUrl(authorizationUrl.toString()));
13699
13836
  log("Browser opened automatically.");
13700
- if (DEBUG) await debugLog(this.serverUrlHash, "Browser opened automatically");
13701
13837
  } catch (error) {
13702
13838
  log("Could not open browser automatically. Please copy and paste the URL above into your browser.");
13703
- if (DEBUG) await debugLog(this.serverUrlHash, "Failed to open browser", error);
13839
+ if (DEBUG) debugLog("Failed to open browser", error);
13704
13840
  }
13705
13841
  }
13706
13842
  /**
@@ -13708,7 +13844,7 @@ ${authorizationUrl.toString()}
13708
13844
  * @param codeVerifier The code verifier to save
13709
13845
  */
13710
13846
  async saveCodeVerifier(codeVerifier) {
13711
- if (DEBUG) await debugLog(this.serverUrlHash, "Saving code verifier");
13847
+ if (DEBUG) debugLog("Saving code verifier");
13712
13848
  await writeTextFile(this.serverUrlHash, "code_verifier.txt", codeVerifier);
13713
13849
  }
13714
13850
  /**
@@ -13716,11 +13852,42 @@ ${authorizationUrl.toString()}
13716
13852
  * @returns The code verifier
13717
13853
  */
13718
13854
  async codeVerifier() {
13719
- if (DEBUG) await debugLog(this.serverUrlHash, "Reading code verifier");
13855
+ if (DEBUG) debugLog("Reading code verifier");
13720
13856
  const verifier = await readTextFile(this.serverUrlHash, "code_verifier.txt", "No code verifier saved for session");
13721
- if (DEBUG) await debugLog(this.serverUrlHash, "Code verifier found:", !!verifier);
13857
+ if (DEBUG) debugLog("Code verifier found:", !!verifier);
13722
13858
  return verifier;
13723
13859
  }
13860
+ /**
13861
+ * Invalidates the specified credentials
13862
+ * @param scope The scope of credentials to invalidate
13863
+ */
13864
+ async invalidateCredentials(scope) {
13865
+ if (DEBUG) debugLog(`Invalidating credentials: ${scope}`);
13866
+ switch (scope) {
13867
+ case "all":
13868
+ await Promise.all([
13869
+ deleteConfigFile(this.serverUrlHash, "client_info.json"),
13870
+ deleteConfigFile(this.serverUrlHash, "tokens.json"),
13871
+ deleteConfigFile(this.serverUrlHash, "code_verifier.txt")
13872
+ ]);
13873
+ if (DEBUG) debugLog("All credentials invalidated");
13874
+ break;
13875
+ case "client":
13876
+ await deleteConfigFile(this.serverUrlHash, "client_info.json");
13877
+ if (DEBUG) debugLog("Client information invalidated");
13878
+ break;
13879
+ case "tokens":
13880
+ await deleteConfigFile(this.serverUrlHash, "tokens.json");
13881
+ if (DEBUG) debugLog("OAuth tokens invalidated");
13882
+ break;
13883
+ case "verifier":
13884
+ await deleteConfigFile(this.serverUrlHash, "code_verifier.txt");
13885
+ if (DEBUG) debugLog("Code verifier invalidated");
13886
+ break;
13887
+ default:
13888
+ throw new Error(`Unknown credential scope: ${scope}`);
13889
+ }
13890
+ }
13724
13891
  };
13725
13892
 
13726
13893
  // src/lib/coordination.ts
@@ -13729,20 +13896,20 @@ import { unlinkSync } from "fs";
13729
13896
  async function isPidRunning(pid2) {
13730
13897
  try {
13731
13898
  process.kill(pid2, 0);
13732
- if (DEBUG) await debugLog(global.currentServerUrlHash, `Process ${pid2} is running`);
13899
+ if (DEBUG) debugLog(`Process ${pid2} is running`);
13733
13900
  return true;
13734
13901
  } catch (err) {
13735
- if (DEBUG) await debugLog(global.currentServerUrlHash, `Process ${pid2} is not running`, err);
13902
+ if (DEBUG) debugLog(`Process ${pid2} is not running`, err);
13736
13903
  return false;
13737
13904
  }
13738
13905
  }
13739
13906
  async function isLockValid(lockData) {
13740
- if (DEBUG) await debugLog(global.currentServerUrlHash, "Checking if lockfile is valid", lockData);
13907
+ if (DEBUG) debugLog("Checking if lockfile is valid", lockData);
13741
13908
  const MAX_LOCK_AGE = 30 * 60 * 1e3;
13742
13909
  if (Date.now() - lockData.timestamp > MAX_LOCK_AGE) {
13743
13910
  log("Lockfile is too old");
13744
13911
  if (DEBUG)
13745
- await debugLog(global.currentServerUrlHash, "Lockfile is too old", {
13912
+ debugLog("Lockfile is too old", {
13746
13913
  age: Date.now() - lockData.timestamp,
13747
13914
  maxAge: MAX_LOCK_AGE
13748
13915
  });
@@ -13750,11 +13917,11 @@ async function isLockValid(lockData) {
13750
13917
  }
13751
13918
  if (!await isPidRunning(lockData.pid)) {
13752
13919
  log("Process from lockfile is not running");
13753
- if (DEBUG) await debugLog(global.currentServerUrlHash, "Process from lockfile is not running", { pid: lockData.pid });
13920
+ if (DEBUG) debugLog("Process from lockfile is not running", { pid: lockData.pid });
13754
13921
  return false;
13755
13922
  }
13756
13923
  try {
13757
- if (DEBUG) await debugLog(global.currentServerUrlHash, "Checking if endpoint is accessible", { port: lockData.port });
13924
+ if (DEBUG) debugLog("Checking if endpoint is accessible", { port: lockData.port });
13758
13925
  const controller = new AbortController();
13759
13926
  const timeout = setTimeout(() => controller.abort(), 1e3);
13760
13927
  const response = await fetch(`http://127.0.0.1:${lockData.port}/wait-for-auth?poll=false`, {
@@ -13762,49 +13929,45 @@ async function isLockValid(lockData) {
13762
13929
  });
13763
13930
  clearTimeout(timeout);
13764
13931
  const isValid2 = response.status === 200 || response.status === 202;
13765
- if (DEBUG)
13766
- await debugLog(global.currentServerUrlHash, `Endpoint check result: ${isValid2 ? "valid" : "invalid"}`, { status: response.status });
13932
+ if (DEBUG) debugLog(`Endpoint check result: ${isValid2 ? "valid" : "invalid"}`, { status: response.status });
13767
13933
  return isValid2;
13768
13934
  } catch (error) {
13769
13935
  log(`Error connecting to auth server: ${error.message}`);
13770
- if (DEBUG) await debugLog(global.currentServerUrlHash, "Error connecting to auth server", error);
13936
+ if (DEBUG) debugLog("Error connecting to auth server", error);
13771
13937
  return false;
13772
13938
  }
13773
13939
  }
13774
13940
  async function waitForAuthentication(port) {
13775
13941
  log(`Waiting for authentication from the server on port ${port}...`);
13776
- if (DEBUG) await debugLog(global.currentServerUrlHash, `Waiting for authentication from server on port ${port}`);
13777
13942
  try {
13778
13943
  let attempts = 0;
13779
13944
  while (true) {
13780
13945
  attempts++;
13781
13946
  const url = `http://127.0.0.1:${port}/wait-for-auth`;
13782
13947
  log(`Querying: ${url}`);
13783
- if (DEBUG) await debugLog(global.currentServerUrlHash, `Poll attempt ${attempts}: ${url}`);
13948
+ if (DEBUG) debugLog(`Poll attempt ${attempts}`);
13784
13949
  try {
13785
13950
  const response = await fetch(url);
13786
- if (DEBUG) await debugLog(global.currentServerUrlHash, `Poll response status: ${response.status}`);
13951
+ if (DEBUG) debugLog(`Poll response status: ${response.status}`);
13787
13952
  if (response.status === 200) {
13788
13953
  log(`Authentication completed by other instance`);
13789
- if (DEBUG) await debugLog(global.currentServerUrlHash, `Authentication completed by other instance`);
13790
13954
  return true;
13791
13955
  } else if (response.status === 202) {
13792
13956
  log(`Authentication still in progress`);
13793
- if (DEBUG) await debugLog(global.currentServerUrlHash, `Authentication still in progress, will retry in 1s`);
13957
+ if (DEBUG) debugLog(`Will retry in 1s`);
13794
13958
  await new Promise((resolve) => setTimeout(resolve, 1e3));
13795
13959
  } else {
13796
13960
  log(`Unexpected response status: ${response.status}`);
13797
- if (DEBUG) await debugLog(global.currentServerUrlHash, `Unexpected response status`, { status: response.status });
13798
13961
  return false;
13799
13962
  }
13800
13963
  } catch (fetchError) {
13801
- if (DEBUG) await debugLog(global.currentServerUrlHash, `Fetch error during poll`, fetchError);
13964
+ if (DEBUG) debugLog(`Fetch error during poll`, fetchError);
13802
13965
  await new Promise((resolve) => setTimeout(resolve, 2e3));
13803
13966
  }
13804
13967
  }
13805
13968
  } catch (error) {
13806
13969
  log(`Error waiting for authentication: ${error.message}`);
13807
- if (DEBUG) await debugLog(global.currentServerUrlHash, `Error waiting for authentication`, error);
13970
+ if (DEBUG) debugLog(`Error waiting for authentication`, error);
13808
13971
  return false;
13809
13972
  }
13810
13973
  }
@@ -13813,43 +13976,39 @@ function createLazyAuthCoordinator(serverUrlHash, callbackPort, events) {
13813
13976
  return {
13814
13977
  initializeAuth: async () => {
13815
13978
  if (authState) {
13816
- if (DEBUG) await debugLog(serverUrlHash, "Auth already initialized, reusing existing state");
13979
+ if (DEBUG) debugLog("Auth already initialized, reusing existing state");
13817
13980
  return authState;
13818
13981
  }
13819
13982
  log("Initializing auth coordination on-demand");
13820
- if (DEBUG) await debugLog(serverUrlHash, "Initializing auth coordination on-demand", { serverUrlHash, callbackPort });
13983
+ if (DEBUG) debugLog("Initializing auth coordination on-demand", { serverUrlHash, callbackPort });
13821
13984
  authState = await coordinateAuth(serverUrlHash, callbackPort, events);
13822
- if (DEBUG) await debugLog(serverUrlHash, "Auth coordination completed", { skipBrowserAuth: authState.skipBrowserAuth });
13985
+ if (DEBUG) debugLog("Auth coordination completed", { skipBrowserAuth: authState.skipBrowserAuth });
13823
13986
  return authState;
13824
13987
  }
13825
13988
  };
13826
13989
  }
13827
13990
  async function coordinateAuth(serverUrlHash, callbackPort, events) {
13828
- if (DEBUG) await debugLog(serverUrlHash, "Coordinating authentication", { serverUrlHash, callbackPort });
13991
+ if (DEBUG) debugLog("Coordinating authentication", { serverUrlHash, callbackPort });
13829
13992
  const lockData = process.platform === "win32" ? null : await checkLockfile(serverUrlHash);
13830
13993
  if (DEBUG) {
13831
13994
  if (process.platform === "win32") {
13832
- await debugLog(serverUrlHash, "Skipping lockfile check on Windows");
13995
+ debugLog("Skipping lockfile check on Windows");
13833
13996
  } else {
13834
- await debugLog(serverUrlHash, "Lockfile check result", { found: !!lockData, lockData });
13997
+ debugLog("Lockfile check result", { found: !!lockData, lockData });
13835
13998
  }
13836
13999
  }
13837
14000
  if (lockData && await isLockValid(lockData)) {
13838
- log(`Another instance is handling authentication on port ${lockData.port}`);
13839
- if (DEBUG) await debugLog(serverUrlHash, "Another instance is handling authentication", { port: lockData.port, pid: lockData.pid });
14001
+ log(`Another instance is handling authentication on port ${lockData.port} (pid: ${lockData.pid})`);
13840
14002
  try {
13841
- if (DEBUG) await debugLog(serverUrlHash, "Waiting for authentication from other instance");
14003
+ if (DEBUG) debugLog("Waiting for authentication from other instance");
13842
14004
  const authCompleted = await waitForAuthentication(lockData.port);
13843
14005
  if (authCompleted) {
13844
- log("Authentication completed by another instance");
13845
- if (DEBUG) await debugLog(serverUrlHash, "Authentication completed by another instance, will use tokens from disk");
14006
+ log("Authentication completed by another instance. Using tokens from disk");
13846
14007
  const dummyServer = express2().listen(0);
13847
14008
  const dummyPort = dummyServer.address().port;
13848
- if (DEBUG) await debugLog(serverUrlHash, "Started dummy server", { port: dummyPort });
14009
+ if (DEBUG) debugLog("Started dummy server", { port: dummyPort });
13849
14010
  const dummyWaitForAuthCode = () => {
13850
14011
  log("WARNING: waitForAuthCode called in secondary instance - this is unexpected");
13851
- if (DEBUG) debugLog(serverUrlHash, "WARNING: waitForAuthCode called in secondary instance - this is unexpected").catch(() => {
13852
- });
13853
14012
  return new Promise(() => {
13854
14013
  });
13855
14014
  };
@@ -13860,20 +14019,18 @@ async function coordinateAuth(serverUrlHash, callbackPort, events) {
13860
14019
  };
13861
14020
  } else {
13862
14021
  log("Taking over authentication process...");
13863
- if (DEBUG) await debugLog(serverUrlHash, "Taking over authentication process");
13864
14022
  }
13865
14023
  } catch (error) {
13866
14024
  log(`Error waiting for authentication: ${error}`);
13867
- if (DEBUG) await debugLog(serverUrlHash, "Error waiting for authentication", error);
14025
+ if (DEBUG) debugLog("Error waiting for authentication", error);
13868
14026
  }
13869
- if (DEBUG) await debugLog(serverUrlHash, "Other instance did not complete auth successfully, deleting lockfile");
14027
+ if (DEBUG) debugLog("Other instance did not complete auth successfully, deleting lockfile");
13870
14028
  await deleteLockfile(serverUrlHash);
13871
14029
  } else if (lockData) {
13872
14030
  log("Found invalid lockfile, deleting it");
13873
- if (DEBUG) await debugLog(serverUrlHash, "Found invalid lockfile, deleting it");
13874
14031
  await deleteLockfile(serverUrlHash);
13875
14032
  }
13876
- if (DEBUG) await debugLog(serverUrlHash, "Setting up OAuth callback server", { port: callbackPort });
14033
+ if (DEBUG) debugLog("Setting up OAuth callback server", { port: callbackPort });
13877
14034
  const { server, waitForAuthCode, authCompletedPromise } = setupOAuthCallbackServerWithLongPoll({
13878
14035
  port: callbackPort,
13879
14036
  path: "/oauth/callback",
@@ -13881,18 +14038,16 @@ async function coordinateAuth(serverUrlHash, callbackPort, events) {
13881
14038
  });
13882
14039
  const address = server.address();
13883
14040
  const actualPort = address.port;
13884
- if (DEBUG) await debugLog(serverUrlHash, "OAuth callback server running", { port: actualPort });
14041
+ if (DEBUG) debugLog("OAuth callback server running", { port: actualPort });
13885
14042
  log(`Creating lockfile for server ${serverUrlHash} with process ${process.pid} on port ${actualPort}`);
13886
- if (DEBUG) await debugLog(serverUrlHash, "Creating lockfile", { serverUrlHash, pid: process.pid, port: actualPort });
13887
14043
  await createLockfile(serverUrlHash, process.pid, actualPort);
13888
14044
  const cleanupHandler = async () => {
13889
14045
  try {
13890
14046
  log(`Cleaning up lockfile for server ${serverUrlHash}`);
13891
- if (DEBUG) await debugLog(serverUrlHash, "Cleaning up lockfile");
13892
14047
  await deleteLockfile(serverUrlHash);
13893
14048
  } catch (error) {
13894
14049
  log(`Error cleaning up lockfile: ${error}`);
13895
- if (DEBUG) await debugLog(serverUrlHash, "Error cleaning up lockfile", error);
14050
+ if (DEBUG) debugLog("Error cleaning up lockfile", error);
13896
14051
  }
13897
14052
  };
13898
14053
  process.once("exit", () => {
@@ -13905,10 +14060,10 @@ async function coordinateAuth(serverUrlHash, callbackPort, events) {
13905
14060
  }
13906
14061
  });
13907
14062
  process.once("SIGINT", async () => {
13908
- if (DEBUG) await debugLog(serverUrlHash, "Received SIGINT signal, cleaning up");
14063
+ if (DEBUG) debugLog("Received SIGINT signal, cleaning up");
13909
14064
  await cleanupHandler();
13910
14065
  });
13911
- if (DEBUG) await debugLog(serverUrlHash, "Auth coordination complete, returning primary instance handlers");
14066
+ if (DEBUG) debugLog("Auth coordination complete, returning primary instance handlers");
13912
14067
  return {
13913
14068
  server,
13914
14069
  waitForAuthCode,
package/dist/client.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  parseCommandLineArgs,
12
12
  setupSignalHandlers,
13
13
  version
14
- } from "./chunk-QAIZEZGG.js";
14
+ } from "./chunk-QW4IRS52.js";
15
15
 
16
16
  // src/client.ts
17
17
  import { EventEmitter } from "events";
package/dist/proxy.js CHANGED
@@ -9,15 +9,15 @@ import {
9
9
  mcpProxy,
10
10
  parseCommandLineArgs,
11
11
  setupSignalHandlers
12
- } from "./chunk-QAIZEZGG.js";
12
+ } from "./chunk-QW4IRS52.js";
13
13
 
14
14
  // src/proxy.ts
15
15
  import { EventEmitter } from "events";
16
16
 
17
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.12.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
17
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
18
18
  import process2 from "node:process";
19
19
 
20
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.12.1/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
20
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
21
21
  var ReadBuffer = class {
22
22
  append(chunk) {
23
23
  this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
@@ -45,7 +45,7 @@ function serializeMessage(message) {
45
45
  return JSON.stringify(message) + "\n";
46
46
  }
47
47
 
48
- // node_modules/.pnpm/@modelcontextprotocol+sdk@1.12.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
48
+ // node_modules/.pnpm/@modelcontextprotocol+sdk@https+++pkg.pr.new+geelen+typescript-sdk+@modelcontextprotocol+sdk@cdf3508/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
49
49
  var StdioServerTransport = class {
50
50
  constructor(_stdin = process2.stdin, _stdout = process2.stdout) {
51
51
  this._stdin = _stdin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-remote",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Remote proxy for Model Context Protocol, allowing local-only clients to connect to remote servers using oAuth",
5
5
  "keywords": [
6
6
  "mcp",
@@ -22,18 +22,27 @@
22
22
  "mcp-remote": "dist/proxy.js",
23
23
  "mcp-remote-client": "dist/client.js"
24
24
  },
25
+ "scripts": {
26
+ "build": "tsup",
27
+ "build:watch": "tsup --watch",
28
+ "check": "prettier --check . && tsc",
29
+ "lint-fix": "prettier --check . --write",
30
+ "test:unit": "vitest run",
31
+ "test:unit:watch": "vitest"
32
+ },
25
33
  "dependencies": {
26
34
  "express": "^4.21.2",
27
35
  "open": "^10.1.0"
28
36
  },
29
37
  "devDependencies": {
30
- "@modelcontextprotocol/sdk": "^1.12.1",
38
+ "@modelcontextprotocol/sdk": "https://pkg.pr.new/geelen/typescript-sdk/@modelcontextprotocol/sdk@cdf3508",
31
39
  "@types/express": "^5.0.0",
32
40
  "@types/node": "^22.13.10",
33
41
  "prettier": "^3.5.3",
34
42
  "tsup": "^8.4.0",
35
43
  "tsx": "^4.19.3",
36
- "typescript": "^5.8.2"
44
+ "typescript": "^5.8.2",
45
+ "vitest": "^3.2.3"
37
46
  },
38
47
  "tsup": {
39
48
  "entry": [
@@ -48,10 +57,12 @@
48
57
  "outDir": "dist",
49
58
  "external": []
50
59
  },
51
- "scripts": {
52
- "build": "tsup",
53
- "build:watch": "tsup --watch",
54
- "check": "prettier --check . && tsc",
55
- "lint-fix": "prettier --check . --write"
56
- }
57
- }
60
+ "vitest": {
61
+ "environment": "node",
62
+ "globals": true,
63
+ "include": [
64
+ "src/**/*.test.ts"
65
+ ]
66
+ },
67
+ "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
68
+ }