mcp-remote 0.1.7 → 0.1.8

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/README.md CHANGED
@@ -152,6 +152,37 @@ npx mcp-remote https://example.remote/server --transport sse-only
152
152
  - `http-only`: Only uses HTTP transport, fails if the server doesn't support it
153
153
  - `sse-only`: Only uses SSE transport, fails if the server doesn't support it
154
154
 
155
+ ### Static OAuth Client Metadata
156
+
157
+ MCP Remote supports providing static OAuth client metadata instead of using the mcp-remote defaults.
158
+ This is useful when connecting to OAuth servers that expect specific client/software IDs or scopes.
159
+
160
+ Provide the client metadata as a JSON string or as a `@` prefixed filepath with the `--static-oauth-client-metadata` flag:
161
+
162
+ ```bash
163
+ npx mcp-remote https://example.remote/server --static-oauth-client-metadata '{ "scope": "space separated scopes" }'
164
+ # uses node readfile, so you probably want to use absolute paths if you're not sure what the cwd is
165
+ npx mcp-remote https://example.remote/server --static-oauth-client-metadata '@/Users/username/Library/Application Support/Claude/oauth_client_metadata.json'
166
+ ```
167
+
168
+ ### Static OAuth Client Information
169
+
170
+ Per the [spec](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization#2-4-dynamic-client-registration),
171
+ servers are encouraged but not required to support [OAuth dynamic client registration](https://datatracker.ietf.org/doc/html/rfc7591).
172
+
173
+ For these servers, MCP Remote supports providing static OAuth client information instead.
174
+ This is useful when connecting to OAuth servers that require pre-registered clients.
175
+
176
+ Provide the client metadata as a JSON string or as a `@` prefixed filepath with the `--static-oauth-client-info` flag:
177
+
178
+ ```bash
179
+ export MCP_REMOTE_CLIENT_ID=xxx
180
+ export MCP_REMOTE_CLIENT_SECRET=yyy
181
+ npx mcp-remote https://example.remote/server --static-oauth-client-info "{ \"client_id\": \"$MCP_REMOTE_CLIENT_ID\", \"client_secret\": \"$MCP_REMOTE_CLIENT_SECRET\" }"
182
+ # uses node readfile, so you probably want to use absolute paths if you're not sure what the cwd is
183
+ npx mcp-remote https://example.remote/server --static-oauth-client-info '@/Users/username/Library/Application Support/Claude/oauth_client_info.json'
184
+ ```
185
+
155
186
  ### Claude Desktop
156
187
 
157
188
  [Official Docs](https://modelcontextprotocol.io/quickstart/user)
@@ -208,7 +239,7 @@ Then restarting your MCP client.
208
239
 
209
240
  ### Check your Node version
210
241
 
211
- Make sure that the version of Node you have installed is [18 or
242
+ Make sure that the version of Node you have installed is [18 or
212
243
  higher](https://modelcontextprotocol.io/quickstart/server). Claude
213
244
  Desktop will use your system version of Node, even if you have a newer
214
245
  version installed elsewhere.
@@ -14,7 +14,7 @@ var require_package = __commonJS({
14
14
  "package.json"(exports, module) {
15
15
  module.exports = {
16
16
  name: "mcp-remote",
17
- version: "0.1.7",
17
+ version: "0.1.8",
18
18
  description: "Remote proxy for Model Context Protocol, allowing local-only clients to connect to remote servers using oAuth",
19
19
  keywords: [
20
20
  "mcp",
@@ -6733,7 +6733,7 @@ async function writeTextFile(serverUrlHash, filename, text) {
6733
6733
  import express from "express";
6734
6734
  import net from "net";
6735
6735
  import crypto2 from "crypto";
6736
- import fs2 from "fs/promises";
6736
+ import fs2, { readFile } from "fs/promises";
6737
6737
  import path2 from "path";
6738
6738
  import os2 from "os";
6739
6739
  var REASON_AUTH_NEEDED = "authentication-needed";
@@ -7005,8 +7005,8 @@ function setupOAuthCallbackServerWithLongPoll(options) {
7005
7005
  Authorization successful!
7006
7006
  You may close this window and return to the CLI.
7007
7007
  <script>
7008
- // If this is a non-interactive session (no manual approval step was required) then
7009
- // this should automatically close the window. If not, this will have no effect and
7008
+ // If this is a non-interactive session (no manual approval step was required) then
7009
+ // this should automatically close the window. If not, this will have no effect and
7010
7010
  // the user will see the message above.
7011
7011
  window.close();
7012
7012
  </script>
@@ -7105,6 +7105,32 @@ async function parseCommandLineArgs(args, usage) {
7105
7105
  host = args[hostIndex + 1];
7106
7106
  log(`Using callback hostname: ${host}`);
7107
7107
  }
7108
+ let staticOAuthClientMetadata = null;
7109
+ const staticOAuthClientMetadataIndex = args.indexOf("--static-oauth-client-metadata");
7110
+ if (staticOAuthClientMetadataIndex !== -1 && staticOAuthClientMetadataIndex < args.length - 1) {
7111
+ const staticOAuthClientMetadataArg = args[staticOAuthClientMetadataIndex + 1];
7112
+ if (staticOAuthClientMetadataArg.startsWith("@")) {
7113
+ const filePath = staticOAuthClientMetadataArg.slice(1);
7114
+ staticOAuthClientMetadata = JSON.parse(await readFile(filePath, "utf8"));
7115
+ log(`Using static OAuth client metadata from file: ${filePath}`);
7116
+ } else {
7117
+ staticOAuthClientMetadata = JSON.parse(staticOAuthClientMetadataArg);
7118
+ log(`Using static OAuth client metadata from string`);
7119
+ }
7120
+ }
7121
+ let staticOAuthClientInfo = null;
7122
+ const staticOAuthClientInfoIndex = args.indexOf("--static-oauth-client-info");
7123
+ if (staticOAuthClientInfoIndex !== -1 && staticOAuthClientInfoIndex < args.length - 1) {
7124
+ const staticOAuthClientInfoArg = args[staticOAuthClientInfoIndex + 1];
7125
+ if (staticOAuthClientInfoArg.startsWith("@")) {
7126
+ const filePath = staticOAuthClientInfoArg.slice(1);
7127
+ staticOAuthClientInfo = JSON.parse(await readFile(filePath, "utf8"));
7128
+ log(`Using static OAuth client information from file: ${filePath}`);
7129
+ } else {
7130
+ staticOAuthClientInfo = JSON.parse(staticOAuthClientInfoArg);
7131
+ log(`Using static OAuth client information from string`);
7132
+ }
7133
+ }
7108
7134
  if (!serverUrl) {
7109
7135
  log(usage);
7110
7136
  process.exit(1);
@@ -7156,7 +7182,7 @@ async function parseCommandLineArgs(args, usage) {
7156
7182
  }
7157
7183
  });
7158
7184
  }
7159
- return { serverUrl, callbackPort, headers, transportStrategy, host, debug };
7185
+ return { serverUrl, callbackPort, headers, transportStrategy, host, debug, staticOAuthClientMetadata, staticOAuthClientInfo };
7160
7186
  }
7161
7187
  function setupSignalHandlers(cleanup) {
7162
7188
  process.on("SIGINT", async () => {
@@ -7190,6 +7216,8 @@ var NodeOAuthClientProvider = class {
7190
7216
  this.clientUri = options.clientUri || "https://github.com/modelcontextprotocol/mcp-cli";
7191
7217
  this.softwareId = options.softwareId || "2e6dc280-f3c3-4e01-99a7-8181dbd1d23d";
7192
7218
  this.softwareVersion = options.softwareVersion || MCP_REMOTE_VERSION;
7219
+ this.staticOAuthClientMetadata = options.staticOAuthClientMetadata;
7220
+ this.staticOAuthClientInfo = options.staticOAuthClientInfo;
7193
7221
  }
7194
7222
  serverUrlHash;
7195
7223
  callbackPath;
@@ -7197,6 +7225,8 @@ var NodeOAuthClientProvider = class {
7197
7225
  clientUri;
7198
7226
  softwareId;
7199
7227
  softwareVersion;
7228
+ staticOAuthClientMetadata;
7229
+ staticOAuthClientInfo;
7200
7230
  get redirectUrl() {
7201
7231
  return `http://${this.options.host}:${this.options.callbackPort}${this.callbackPath}`;
7202
7232
  }
@@ -7209,7 +7239,8 @@ var NodeOAuthClientProvider = class {
7209
7239
  client_name: this.clientName,
7210
7240
  client_uri: this.clientUri,
7211
7241
  software_id: this.softwareId,
7212
- software_version: this.softwareVersion
7242
+ software_version: this.softwareVersion,
7243
+ ...this.staticOAuthClientMetadata
7213
7244
  };
7214
7245
  }
7215
7246
  /**
@@ -7218,6 +7249,10 @@ var NodeOAuthClientProvider = class {
7218
7249
  */
7219
7250
  async clientInformation() {
7220
7251
  if (DEBUG) await debugLog(this.serverUrlHash, "Reading client info");
7252
+ if (this.staticOAuthClientInfo) {
7253
+ if (DEBUG) await debugLog(this.serverUrlHash, "Returning static client info");
7254
+ return this.staticOAuthClientInfo;
7255
+ }
7221
7256
  const clientInfo = await readJsonFile(this.serverUrlHash, "client_info.json", OAuthClientInformationFullSchema);
7222
7257
  if (DEBUG) await debugLog(this.serverUrlHash, "Client info result:", clientInfo ? "Found" : "Not found");
7223
7258
  return clientInfo;
package/dist/client.js CHANGED
@@ -11,11 +11,11 @@ import {
11
11
  log,
12
12
  parseCommandLineArgs,
13
13
  setupSignalHandlers
14
- } from "./chunk-ETC3CC4Y.js";
14
+ } from "./chunk-WTVTTD74.js";
15
15
 
16
16
  // src/client.ts
17
17
  import { EventEmitter } from "events";
18
- async function runClient(serverUrl, callbackPort, headers, transportStrategy = "http-first", host) {
18
+ async function runClient(serverUrl, callbackPort, headers, transportStrategy = "http-first", host, staticOAuthClientMetadata, staticOAuthClientInfo) {
19
19
  const events = new EventEmitter();
20
20
  const serverUrlHash = getServerUrlHash(serverUrl);
21
21
  const authCoordinator = createLazyAuthCoordinator(serverUrlHash, callbackPort, events);
@@ -23,7 +23,9 @@ async function runClient(serverUrl, callbackPort, headers, transportStrategy = "
23
23
  serverUrl,
24
24
  callbackPort,
25
25
  host,
26
- clientName: "MCP CLI Client"
26
+ clientName: "MCP CLI Client",
27
+ staticOAuthClientMetadata,
28
+ staticOAuthClientInfo
27
29
  });
28
30
  const client = new Client(
29
31
  {
@@ -95,8 +97,8 @@ async function runClient(serverUrl, callbackPort, headers, transportStrategy = "
95
97
  process.exit(1);
96
98
  }
97
99
  }
98
- parseCommandLineArgs(process.argv.slice(2), "Usage: npx tsx client.ts <https://server-url> [callback-port] [--debug]").then(({ serverUrl, callbackPort, headers, transportStrategy, host, debug }) => {
99
- return runClient(serverUrl, callbackPort, headers, transportStrategy, host);
100
+ parseCommandLineArgs(process.argv.slice(2), "Usage: npx tsx client.ts <https://server-url> [callback-port] [--debug]").then(({ serverUrl, callbackPort, headers, transportStrategy, host, staticOAuthClientMetadata, staticOAuthClientInfo }) => {
101
+ return runClient(serverUrl, callbackPort, headers, transportStrategy, host, staticOAuthClientMetadata, staticOAuthClientInfo);
100
102
  }).catch((error) => {
101
103
  console.error("Fatal error:", error);
102
104
  process.exit(1);
package/dist/proxy.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  mcpProxy,
10
10
  parseCommandLineArgs,
11
11
  setupSignalHandlers
12
- } from "./chunk-ETC3CC4Y.js";
12
+ } from "./chunk-WTVTTD74.js";
13
13
 
14
14
  // src/proxy.ts
15
15
  import { EventEmitter } from "events";
@@ -110,7 +110,7 @@ var StdioServerTransport = class {
110
110
  };
111
111
 
112
112
  // src/proxy.ts
113
- async function runProxy(serverUrl, callbackPort, headers, transportStrategy = "http-first", host) {
113
+ async function runProxy(serverUrl, callbackPort, headers, transportStrategy = "http-first", host, staticOAuthClientMetadata, staticOAuthClientInfo) {
114
114
  const events = new EventEmitter();
115
115
  const serverUrlHash = getServerUrlHash(serverUrl);
116
116
  const authCoordinator = createLazyAuthCoordinator(serverUrlHash, callbackPort, events);
@@ -118,7 +118,9 @@ async function runProxy(serverUrl, callbackPort, headers, transportStrategy = "h
118
118
  serverUrl,
119
119
  callbackPort,
120
120
  host,
121
- clientName: "MCP CLI Proxy"
121
+ clientName: "MCP CLI Proxy",
122
+ staticOAuthClientMetadata,
123
+ staticOAuthClientInfo
122
124
  });
123
125
  const localTransport = new StdioServerTransport();
124
126
  let server = null;
@@ -182,8 +184,8 @@ to the CA certificate file. If using claude_desktop_config.json, this might look
182
184
  process.exit(1);
183
185
  }
184
186
  }
185
- parseCommandLineArgs(process.argv.slice(2), "Usage: npx tsx proxy.ts <https://server-url> [callback-port] [--debug]").then(({ serverUrl, callbackPort, headers, transportStrategy, host, debug }) => {
186
- return runProxy(serverUrl, callbackPort, headers, transportStrategy, host);
187
+ parseCommandLineArgs(process.argv.slice(2), "Usage: npx tsx proxy.ts <https://server-url> [callback-port] [--debug]").then(({ serverUrl, callbackPort, headers, transportStrategy, host, debug, staticOAuthClientMetadata, staticOAuthClientInfo }) => {
188
+ return runProxy(serverUrl, callbackPort, headers, transportStrategy, host, staticOAuthClientMetadata, staticOAuthClientInfo);
187
189
  }).catch((error) => {
188
190
  log("Fatal error:", error);
189
191
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-remote",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
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",