mcp-remote 0.0.10-3 → 0.0.11

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
@@ -16,17 +16,7 @@ That's where `mcp-remote` comes in. As soon as your chosen MCP client supports r
16
16
 
17
17
  ## Usage
18
18
 
19
- ### Claude Desktop
20
-
21
- [Official Docs](https://modelcontextprotocol.io/quickstart/user)
22
-
23
- In order to add an MCP server to Claude Desktop you need to edit the configuration file located at:
24
-
25
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
26
-
27
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
28
-
29
- If it does not exist yet, [you may need to enable it under Settings > Developer](https://modelcontextprotocol.io/quickstart/user#2-add-the-filesystem-mcp-server).
19
+ All the most popular MCP clients (Claude Desktop, Cursor & Windsurf) use the following config format:
30
20
 
31
21
  ```json
32
22
  {
@@ -34,7 +24,6 @@ If it does not exist yet, [you may need to enable it under Settings > Developer]
34
24
  "remote-example": {
35
25
  "command": "npx",
36
26
  "args": [
37
- "-y",
38
27
  "mcp-remote",
39
28
  "https://remote.mcp.server/sse"
40
29
  ]
@@ -43,52 +32,75 @@ If it does not exist yet, [you may need to enable it under Settings > Developer]
43
32
  }
44
33
  ```
45
34
 
46
- Restart Claude Desktop to pick up the changes in the configuration file.
47
- Upon restarting, you should see a hammer icon in the bottom right corner
48
- of the input box.
49
-
50
- ### Cursor
51
-
52
- [Official Docs](https://docs.cursor.com/context/model-context-protocol)
35
+ ### Flags
53
36
 
54
- Add the following configuration to `~/.cursor/mcp.json`:
37
+ * If `npx` is producing errors, consider adding `-y` as the first argument to auto-accept the installation of the `mcp-remote` package.
55
38
 
56
39
  ```json
57
- {
58
- "mcpServers": {
59
- "remote-example": {
60
40
  "command": "npx",
61
41
  "args": [
62
- "-y",
42
+ "-y"
63
43
  "mcp-remote",
64
44
  "https://remote.mcp.server/sse"
65
45
  ]
66
- }
67
- }
68
- }
69
46
  ```
70
47
 
71
- ### Windsurf
48
+ * To force `npx` to always check for an updated version of `mcp-remote`, add the `@latest` flag:
72
49
 
73
- [Official Docs](https://docs.codeium.com/windsurf/mcp)
50
+ ```json
51
+ "args": [
52
+ "mcp-remote@latest",
53
+ "https://remote.mcp.server/sse"
54
+ ]
55
+ ```
74
56
 
75
- Add the following configuration to `~/.codeium/windsurf/mcp_config.json`:
57
+ * To force `mcp-remote` to ignore any existing access tokens and begin the authorization flow anew, pass `--clean`.
76
58
 
77
59
  ```json
78
- {
79
- "mcpServers": {
80
- "remote-example": {
81
- "command": "npx",
82
60
  "args": [
83
- "-y",
84
61
  "mcp-remote",
85
- "https://remote.mcp.server/sse"
62
+ "https://remote.mcp.server/sse",
63
+ "--clean"
64
+ ]
65
+ ```
66
+
67
+ * To change which port `mcp-remote` listens for an OAuth redirect (by default `3334`), add an additional argument after the server URL. Note that whatever port you specify, if it is unavailable an open port will be chosen at random.
68
+
69
+ ```json
70
+ "args": [
71
+ "mcp-remote",
72
+ "https://remote.mcp.server/sse",
73
+ "9696"
86
74
  ]
87
- }
88
- }
89
- }
90
75
  ```
91
76
 
77
+ * To ensure that no
78
+
79
+ ### Claude Desktop
80
+
81
+ [Official Docs](https://modelcontextprotocol.io/quickstart/user)
82
+
83
+ In order to add an MCP server to Claude Desktop you need to edit the configuration file located at:
84
+
85
+ * macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
86
+ * Windows: `%APPDATA%\Claude\claude_desktop_config.json`
87
+
88
+ If it does not exist yet, [you may need to enable it under Settings > Developer](https://modelcontextprotocol.io/quickstart/user#2-add-the-filesystem-mcp-server).
89
+
90
+ Restart Claude Desktop to pick up the changes in the configuration file.
91
+ Upon restarting, you should see a hammer icon in the bottom right corner
92
+ of the input box.
93
+
94
+ ### Cursor
95
+
96
+ [Official Docs](https://docs.cursor.com/context/model-context-protocol). The configuration file is located at `~/.cursor/mcp.json`.
97
+
98
+ As of version `0.48.0`, Cursor supports unauthed SSE servers directly. If your MCP server is using the official MCP OAuth authorization protocol, you still need to add a **"command"** server and call `mcp-remote`.
99
+
100
+ ### Windsurf
101
+
102
+ [Official Docs](https://docs.codeium.com/windsurf/mcp). The configuration file is located at `~/.codeium/windsurf/mcp_config.json`.
103
+
92
104
  ## Building Remote MCP Servers
93
105
 
94
106
  For instructions on building & deploying remote MCP servers, including acting as a valid OAuth client, see the following resources:
@@ -106,7 +118,17 @@ For more information about testing these servers, see also:
106
118
 
107
119
  Know of more resources you'd like to share? Please add them to this Readme and send a PR!
108
120
 
109
- ## Debugging
121
+ ## Troubleshooting
122
+
123
+ ### Wipe your `~/.mcp-auth` directory
124
+
125
+ `mcp-remote` stores all the credential information inside `~/.mcp-auth` (or wherever your `MCP_REMOTE_CONFIG_DIR` points to). If you're having persistent issues, try running:
126
+
127
+ ```sh
128
+ rm -rf ~/.mcp-auth
129
+ ```
130
+
131
+ Then restarting your MCP client.
110
132
 
111
133
  ### Check your Node version
112
134
 
@@ -141,3 +163,19 @@ this might look like:
141
163
  }
142
164
  }
143
165
  ```
166
+
167
+ ### Check the logs
168
+
169
+ [Follow Claude Desktop logs in real-time](https://modelcontextprotocol.io/docs/tools/debugging#debugging-in-claude-desktop)
170
+
171
+ MacOS / Linux:
172
+
173
+ `tail -n 20 -F ~/Library/Logs/Claude/mcp*.log`
174
+
175
+ For bash on WSL:
176
+
177
+ `tail -n 20 -f "C:\Users\YourUsername\AppData\Local\Claude\Logs\mcp.log"`
178
+
179
+ or Powershell:
180
+
181
+ `Get-Content "C:\Users\YourUsername\AppData\Local\Claude\Logs\mcp.log" -Wait -Tail 20`
@@ -0,0 +1,382 @@
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __commonJS = (cb, mod) => function __require() {
3
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
4
+ };
5
+
6
+ // src/lib/node-oauth-client-provider.ts
7
+ import open from "open";
8
+ import {
9
+ OAuthClientInformationSchema,
10
+ OAuthTokensSchema
11
+ } from "@modelcontextprotocol/sdk/shared/auth.js";
12
+
13
+ // src/lib/mcp-auth-config.ts
14
+ import crypto from "crypto";
15
+ import path from "path";
16
+ import os from "os";
17
+ import fs from "fs/promises";
18
+ var knownConfigFiles = [
19
+ "client_info.json",
20
+ "tokens.json",
21
+ "code_verifier.txt"
22
+ ];
23
+ async function cleanServerConfig(serverUrlHash) {
24
+ console.error(`Cleaning configuration files for server: ${serverUrlHash}`);
25
+ for (const filename of knownConfigFiles) {
26
+ await deleteConfigFile(serverUrlHash, filename);
27
+ }
28
+ }
29
+ function getConfigDir() {
30
+ return process.env.MCP_REMOTE_CONFIG_DIR || path.join(os.homedir(), ".mcp-auth");
31
+ }
32
+ async function ensureConfigDir() {
33
+ try {
34
+ const configDir = getConfigDir();
35
+ await fs.mkdir(configDir, { recursive: true });
36
+ } catch (error) {
37
+ console.error("Error creating config directory:", error);
38
+ throw error;
39
+ }
40
+ }
41
+ function getServerUrlHash(serverUrl) {
42
+ return crypto.createHash("md5").update(serverUrl).digest("hex");
43
+ }
44
+ function getConfigFilePath(serverUrlHash, filename) {
45
+ const configDir = getConfigDir();
46
+ return path.join(configDir, `${serverUrlHash}_${filename}`);
47
+ }
48
+ async function deleteConfigFile(serverUrlHash, filename) {
49
+ try {
50
+ const filePath = getConfigFilePath(serverUrlHash, filename);
51
+ await fs.unlink(filePath);
52
+ } catch (error) {
53
+ if (error.code !== "ENOENT") {
54
+ console.error(`Error deleting ${filename}:`, error);
55
+ }
56
+ }
57
+ }
58
+ async function readJsonFile(serverUrlHash, filename, schema, clean = false) {
59
+ try {
60
+ await ensureConfigDir();
61
+ if (clean) {
62
+ await deleteConfigFile(serverUrlHash, filename);
63
+ return void 0;
64
+ }
65
+ const filePath = getConfigFilePath(serverUrlHash, filename);
66
+ const content = await fs.readFile(filePath, "utf-8");
67
+ return await schema.parseAsync(JSON.parse(content));
68
+ } catch (error) {
69
+ if (error.code === "ENOENT") {
70
+ return void 0;
71
+ }
72
+ return void 0;
73
+ }
74
+ }
75
+ async function writeJsonFile(serverUrlHash, filename, data) {
76
+ try {
77
+ await ensureConfigDir();
78
+ const filePath = getConfigFilePath(serverUrlHash, filename);
79
+ await fs.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
80
+ } catch (error) {
81
+ console.error(`Error writing ${filename}:`, error);
82
+ throw error;
83
+ }
84
+ }
85
+ async function readTextFile(serverUrlHash, filename, errorMessage, clean = false) {
86
+ try {
87
+ await ensureConfigDir();
88
+ if (clean) {
89
+ await deleteConfigFile(serverUrlHash, filename);
90
+ throw new Error("File deleted due to clean flag");
91
+ }
92
+ const filePath = getConfigFilePath(serverUrlHash, filename);
93
+ return await fs.readFile(filePath, "utf-8");
94
+ } catch (error) {
95
+ throw new Error(errorMessage || `Error reading ${filename}`);
96
+ }
97
+ }
98
+ async function writeTextFile(serverUrlHash, filename, text) {
99
+ try {
100
+ await ensureConfigDir();
101
+ const filePath = getConfigFilePath(serverUrlHash, filename);
102
+ await fs.writeFile(filePath, text, "utf-8");
103
+ } catch (error) {
104
+ console.error(`Error writing ${filename}:`, error);
105
+ throw error;
106
+ }
107
+ }
108
+
109
+ // src/lib/node-oauth-client-provider.ts
110
+ var NodeOAuthClientProvider = class {
111
+ /**
112
+ * Creates a new NodeOAuthClientProvider
113
+ * @param options Configuration options for the provider
114
+ */
115
+ constructor(options) {
116
+ this.options = options;
117
+ this.serverUrlHash = getServerUrlHash(options.serverUrl);
118
+ this.callbackPath = options.callbackPath || "/oauth/callback";
119
+ this.clientName = options.clientName || "MCP CLI Client";
120
+ this.clientUri = options.clientUri || "https://github.com/modelcontextprotocol/mcp-cli";
121
+ if (options.clean) {
122
+ cleanServerConfig(this.serverUrlHash).catch((err) => {
123
+ console.error("Error cleaning server config:", err);
124
+ });
125
+ }
126
+ }
127
+ serverUrlHash;
128
+ callbackPath;
129
+ clientName;
130
+ clientUri;
131
+ get redirectUrl() {
132
+ return `http://127.0.0.1:${this.options.callbackPort}${this.callbackPath}`;
133
+ }
134
+ get clientMetadata() {
135
+ return {
136
+ redirect_uris: [this.redirectUrl],
137
+ token_endpoint_auth_method: "none",
138
+ grant_types: ["authorization_code", "refresh_token"],
139
+ response_types: ["code"],
140
+ client_name: this.clientName,
141
+ client_uri: this.clientUri
142
+ };
143
+ }
144
+ /**
145
+ * Gets the client information if it exists
146
+ * @returns The client information or undefined
147
+ */
148
+ async clientInformation() {
149
+ return readJsonFile(
150
+ this.serverUrlHash,
151
+ "client_info.json",
152
+ OAuthClientInformationSchema,
153
+ this.options.clean
154
+ );
155
+ }
156
+ /**
157
+ * Saves client information
158
+ * @param clientInformation The client information to save
159
+ */
160
+ async saveClientInformation(clientInformation) {
161
+ await writeJsonFile(this.serverUrlHash, "client_info.json", clientInformation);
162
+ }
163
+ /**
164
+ * Gets the OAuth tokens if they exist
165
+ * @returns The OAuth tokens or undefined
166
+ */
167
+ async tokens() {
168
+ return readJsonFile(
169
+ this.serverUrlHash,
170
+ "tokens.json",
171
+ OAuthTokensSchema,
172
+ this.options.clean
173
+ );
174
+ }
175
+ /**
176
+ * Saves OAuth tokens
177
+ * @param tokens The tokens to save
178
+ */
179
+ async saveTokens(tokens) {
180
+ await writeJsonFile(this.serverUrlHash, "tokens.json", tokens);
181
+ }
182
+ /**
183
+ * Redirects the user to the authorization URL
184
+ * @param authorizationUrl The URL to redirect to
185
+ */
186
+ async redirectToAuthorization(authorizationUrl) {
187
+ console.error(`
188
+ Please authorize this client by visiting:
189
+ ${authorizationUrl.toString()}
190
+ `);
191
+ try {
192
+ await open(authorizationUrl.toString());
193
+ console.error("Browser opened automatically.");
194
+ } catch (error) {
195
+ console.error("Could not open browser automatically. Please copy and paste the URL above into your browser.");
196
+ }
197
+ }
198
+ /**
199
+ * Saves the PKCE code verifier
200
+ * @param codeVerifier The code verifier to save
201
+ */
202
+ async saveCodeVerifier(codeVerifier) {
203
+ await writeTextFile(this.serverUrlHash, "code_verifier.txt", codeVerifier);
204
+ }
205
+ /**
206
+ * Gets the PKCE code verifier
207
+ * @returns The code verifier
208
+ */
209
+ async codeVerifier() {
210
+ return await readTextFile(
211
+ this.serverUrlHash,
212
+ "code_verifier.txt",
213
+ "No code verifier saved for session",
214
+ this.options.clean
215
+ );
216
+ }
217
+ };
218
+
219
+ // src/lib/utils.ts
220
+ import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
221
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
222
+ import express from "express";
223
+ import net from "net";
224
+ var pid = process.pid;
225
+ function mcpProxy({ transportToClient, transportToServer }) {
226
+ let transportToClientClosed = false;
227
+ let transportToServerClosed = false;
228
+ transportToClient.onmessage = (message) => {
229
+ console.error("[Local\u2192Remote]", message.method || message.id);
230
+ transportToServer.send(message).catch(onServerError);
231
+ };
232
+ transportToServer.onmessage = (message) => {
233
+ console.error("[Remote\u2192Local]", message.method || message.id);
234
+ transportToClient.send(message).catch(onClientError);
235
+ };
236
+ transportToClient.onclose = () => {
237
+ if (transportToServerClosed) {
238
+ return;
239
+ }
240
+ transportToClientClosed = true;
241
+ transportToServer.close().catch(onServerError);
242
+ };
243
+ transportToServer.onclose = () => {
244
+ if (transportToClientClosed) {
245
+ return;
246
+ }
247
+ transportToServerClosed = true;
248
+ transportToClient.close().catch(onClientError);
249
+ };
250
+ transportToClient.onerror = onClientError;
251
+ transportToServer.onerror = onServerError;
252
+ function onClientError(error) {
253
+ console.error("Error from local client:", error);
254
+ }
255
+ function onServerError(error) {
256
+ console.error("Error from remote server:", error);
257
+ }
258
+ }
259
+ async function connectToRemoteServer(serverUrl, authProvider, waitForAuthCode) {
260
+ console.error(`[${pid}] Connecting to remote server: ${serverUrl}`);
261
+ const url = new URL(serverUrl);
262
+ const transport = new SSEClientTransport(url, { authProvider });
263
+ try {
264
+ await transport.start();
265
+ console.error("Connected to remote server");
266
+ return transport;
267
+ } catch (error) {
268
+ if (error instanceof UnauthorizedError || error instanceof Error && error.message.includes("Unauthorized")) {
269
+ console.error("Authentication required. Waiting for authorization...");
270
+ const code = await waitForAuthCode();
271
+ try {
272
+ console.error("Completing authorization...");
273
+ await transport.finishAuth(code);
274
+ const newTransport = new SSEClientTransport(url, { authProvider });
275
+ await newTransport.start();
276
+ console.error("Connected to remote server after authentication");
277
+ return newTransport;
278
+ } catch (authError) {
279
+ console.error("Authorization error:", authError);
280
+ throw authError;
281
+ }
282
+ } else {
283
+ console.error("Connection error:", error);
284
+ throw error;
285
+ }
286
+ }
287
+ }
288
+ function setupOAuthCallbackServer(options) {
289
+ let authCode = null;
290
+ const app = express();
291
+ app.get(options.path, (req, res) => {
292
+ const code = req.query.code;
293
+ if (!code) {
294
+ res.status(400).send("Error: No authorization code received");
295
+ return;
296
+ }
297
+ authCode = code;
298
+ res.send("Authorization successful! You may close this window and return to the CLI.");
299
+ options.events.emit("auth-code-received", code);
300
+ });
301
+ const server = app.listen(options.port, () => {
302
+ console.error(`OAuth callback server running at http://127.0.0.1:${options.port}`);
303
+ });
304
+ const waitForAuthCode = () => {
305
+ return new Promise((resolve) => {
306
+ if (authCode) {
307
+ resolve(authCode);
308
+ return;
309
+ }
310
+ options.events.once("auth-code-received", (code) => {
311
+ resolve(code);
312
+ });
313
+ });
314
+ };
315
+ return { server, authCode, waitForAuthCode };
316
+ }
317
+ async function findAvailablePort(preferredPort) {
318
+ return new Promise((resolve, reject) => {
319
+ const server = net.createServer();
320
+ server.on("error", (err) => {
321
+ if (err.code === "EADDRINUSE") {
322
+ server.listen(0);
323
+ } else {
324
+ reject(err);
325
+ }
326
+ });
327
+ server.on("listening", () => {
328
+ const { port } = server.address();
329
+ server.close(() => {
330
+ resolve(port);
331
+ });
332
+ });
333
+ server.listen(preferredPort || 0);
334
+ });
335
+ }
336
+ async function parseCommandLineArgs(args, defaultPort, usage) {
337
+ const cleanIndex = args.indexOf("--clean");
338
+ const clean = cleanIndex !== -1;
339
+ if (clean) {
340
+ args.splice(cleanIndex, 1);
341
+ }
342
+ const serverUrl = args[0];
343
+ const specifiedPort = args[1] ? parseInt(args[1]) : void 0;
344
+ if (!serverUrl) {
345
+ console.error(usage);
346
+ process.exit(1);
347
+ }
348
+ const url = new URL(serverUrl);
349
+ const isLocalhost = (url.hostname === "localhost" || url.hostname === "127.0.0.1") && url.protocol === "http:";
350
+ if (!(url.protocol == "https:" || isLocalhost)) {
351
+ console.error(usage);
352
+ process.exit(1);
353
+ }
354
+ const callbackPort = specifiedPort || await findAvailablePort(defaultPort);
355
+ if (specifiedPort) {
356
+ console.error(`Using specified callback port: ${callbackPort}`);
357
+ } else {
358
+ console.error(`Using automatically selected callback port: ${callbackPort}`);
359
+ }
360
+ if (clean) {
361
+ console.error("Clean mode enabled: config files will be reset before reading");
362
+ }
363
+ return { serverUrl, callbackPort, clean };
364
+ }
365
+ function setupSignalHandlers(cleanup) {
366
+ process.on("SIGINT", async () => {
367
+ console.error("\nShutting down...");
368
+ await cleanup();
369
+ process.exit(0);
370
+ });
371
+ process.stdin.resume();
372
+ }
373
+
374
+ export {
375
+ __commonJS,
376
+ NodeOAuthClientProvider,
377
+ mcpProxy,
378
+ connectToRemoteServer,
379
+ setupOAuthCallbackServer,
380
+ parseCommandLineArgs,
381
+ setupSignalHandlers
382
+ };
@@ -1,33 +1,98 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  NodeOAuthClientProvider,
4
+ __commonJS,
4
5
  parseCommandLineArgs,
5
6
  setupOAuthCallbackServer,
6
7
  setupSignalHandlers
7
- } from "../chunk-S3VO5IXF.js";
8
+ } from "./chunk-W4HND3T7.js";
8
9
 
9
- // src/cli/client.ts
10
+ // package.json
11
+ var require_package = __commonJS({
12
+ "package.json"(exports, module) {
13
+ module.exports = {
14
+ name: "mcp-remote",
15
+ version: "0.0.10",
16
+ description: "Remote proxy for Model Context Protocol, allowing local-only clients to connect to remote servers using oAuth",
17
+ keywords: [
18
+ "mcp",
19
+ "stdio",
20
+ "sse",
21
+ "remote",
22
+ "oauth"
23
+ ],
24
+ author: "Glen Maddern <glen@cloudflare.com>",
25
+ repository: "https://github.com/geelen/remote-mcp",
26
+ type: "module",
27
+ files: [
28
+ "dist",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ main: "dist/index.js",
33
+ bin: {
34
+ "mcp-remote": "dist/cli/proxy.js"
35
+ },
36
+ scripts: {
37
+ dev: "tsup --watch",
38
+ build: "tsup",
39
+ check: "prettier --check . && tsc"
40
+ },
41
+ dependencies: {
42
+ "@modelcontextprotocol/sdk": "^1.7.0",
43
+ express: "^4.21.2",
44
+ open: "^10.1.0"
45
+ },
46
+ devDependencies: {
47
+ "@types/express": "^5.0.0",
48
+ "@types/node": "^22.13.10",
49
+ "@types/react": "^19.0.12",
50
+ prettier: "^3.5.3",
51
+ react: "^19.0.0",
52
+ tsup: "^8.4.0",
53
+ tsx: "^4.19.3",
54
+ typescript: "^5.8.2"
55
+ },
56
+ tsup: {
57
+ entry: [
58
+ "src/client.ts",
59
+ "src/proxy.ts"
60
+ ],
61
+ format: [
62
+ "esm"
63
+ ],
64
+ dts: true,
65
+ clean: true,
66
+ outDir: "dist",
67
+ external: [
68
+ "react"
69
+ ]
70
+ }
71
+ };
72
+ }
73
+ });
74
+
75
+ // src/client.ts
10
76
  import { EventEmitter } from "events";
11
77
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
12
78
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
13
79
  import { ListResourcesResultSchema, ListToolsResultSchema } from "@modelcontextprotocol/sdk/types.js";
14
80
  import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
15
- async function runClient(serverUrl, callbackPort) {
81
+ async function runClient(serverUrl, callbackPort, clean = false) {
16
82
  const events = new EventEmitter();
17
83
  const authProvider = new NodeOAuthClientProvider({
18
84
  serverUrl,
19
85
  callbackPort,
20
- clientName: "MCP CLI Client"
86
+ clientName: "MCP CLI Client",
87
+ clean
21
88
  });
22
89
  const client = new Client(
23
90
  {
24
- name: "mcp-cli",
25
- version: "0.1.0"
91
+ name: "mcp-remote",
92
+ version: require_package().version
26
93
  },
27
94
  {
28
- capabilities: {
29
- sampling: {}
30
- }
95
+ capabilities: {}
31
96
  }
32
97
  );
33
98
  const url = new URL(serverUrl);
@@ -105,8 +170,8 @@ async function runClient(serverUrl, callbackPort) {
105
170
  }
106
171
  console.log("Listening for messages. Press Ctrl+C to exit.");
107
172
  }
108
- parseCommandLineArgs(process.argv.slice(2), 3333, "Usage: npx tsx client.ts <https://server-url> [callback-port]").then(({ serverUrl, callbackPort }) => {
109
- return runClient(serverUrl, callbackPort);
173
+ parseCommandLineArgs(process.argv.slice(2), 3333, "Usage: npx tsx client.ts [--clean] <https://server-url> [callback-port]").then(({ serverUrl, callbackPort, clean }) => {
174
+ return runClient(serverUrl, callbackPort, clean);
110
175
  }).catch((error) => {
111
176
  console.error("Fatal error:", error);
112
177
  process.exit(1);