diff --git a/src/client.ts b/src/client.ts index 4e0c14c..d87599c 100644 --- a/src/client.ts +++ b/src/client.ts @@ -151,7 +151,7 @@ async function runClient( } // Parse command-line arguments and run the client -parseCommandLineArgs(process.argv.slice(2), 3333, 'Usage: npx tsx client.ts [callback-port]') +parseCommandLineArgs(process.argv.slice(2), 'Usage: npx tsx client.ts [callback-port]') .then(({ serverUrl, callbackPort, headers, transportStrategy }) => { return runClient(serverUrl, callbackPort, headers, transportStrategy) }) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index f5d4df0..a0a60dc 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -4,6 +4,12 @@ import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js' import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js' import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js' import { OAuthClientInformationFull, OAuthClientInformationFullSchema } from '@modelcontextprotocol/sdk/shared/auth.js' +import { OAuthCallbackServerOptions } from './types' +import { getConfigFilePath, readJsonFile } from './mcp-auth-config' +import express from 'express' +import net from 'net' +import crypto from 'crypto' +import fs from 'fs/promises' // Connection constants export const REASON_AUTH_NEEDED = 'authentication-needed' @@ -11,12 +17,6 @@ export const REASON_TRANSPORT_FALLBACK = 'falling-back-to-alternate-transport' // Transport strategy types export type TransportStrategy = 'sse-only' | 'http-only' | 'sse-first' | 'http-first' -import { OAuthCallbackServerOptions } from './types' -import { getConfigFilePath, readJsonFile } from './mcp-auth-config' -import express from 'express' -import net from 'net' -import crypto from 'crypto' -import fs from 'fs/promises' // Package version from package.json export const MCP_REMOTE_VERSION = require('../../package.json').version @@ -355,8 +355,7 @@ export function setupOAuthCallbackServer(options: OAuthCallbackServerOptions) { return { server, authCode, waitForAuthCode } } -async function findExistingClientPort(serverUrl: string): Promise { - const serverUrlHash = getServerUrlHash(serverUrl) +async function findExistingClientPort(serverUrlHash: string): Promise { const clientInfo = await readJsonFile(serverUrlHash, 'client_info.json', OAuthClientInformationFullSchema) if (!clientInfo) { return undefined @@ -370,6 +369,13 @@ async function findExistingClientPort(serverUrl: string): Promise /** * Parses command line arguments for MCP clients and proxies * @param args Command line arguments - * @param defaultPort Default port for the callback server if specified port is unavailable * @param usage Usage message to show on error * @returns A promise that resolves to an object with parsed serverUrl, callbackPort and headers */ -export async function parseCommandLineArgs(args: string[], defaultPort: number, usage: string) { +export async function parseCommandLineArgs(args: string[], usage: string) { // Process headers const headers: Record = {} let i = 0 @@ -457,9 +462,11 @@ export async function parseCommandLineArgs(args: string[], defaultPort: number, log(usage) process.exit(1) } + const serverUrlHash = getServerUrlHash(serverUrl) + const defaultPort = calculateDefaultPort(serverUrlHash) // Use the specified port, or the existing client port or fallback to find an available one - const [existingClientPort, availablePort] = await Promise.all([findExistingClientPort(serverUrl), findAvailablePort(defaultPort)]) + const [existingClientPort, availablePort] = await Promise.all([findExistingClientPort(serverUrlHash), findAvailablePort(defaultPort)]) let callbackPort: number if (specifiedPort) { @@ -467,7 +474,7 @@ export async function parseCommandLineArgs(args: string[], defaultPort: number, log( `Warning! Specified callback port of ${specifiedPort}, which conflicts with existing client registration port ${existingClientPort}. Deleting existing client data to force reregistration.`, ) - await fs.rm(getConfigFilePath(getServerUrlHash(serverUrl), 'client_info.json')) + await fs.rm(getConfigFilePath(serverUrlHash, 'client_info.json')) } log(`Using specified callback port: ${specifiedPort}`) callbackPort = specifiedPort diff --git a/src/proxy.ts b/src/proxy.ts index 7263a95..535bfe2 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -135,7 +135,7 @@ to the CA certificate file. If using claude_desktop_config.json, this might look } // Parse command-line arguments and run the proxy -parseCommandLineArgs(process.argv.slice(2), 3334, 'Usage: npx tsx proxy.ts [callback-port]') +parseCommandLineArgs(process.argv.slice(2), 'Usage: npx tsx proxy.ts [callback-port]') .then(({ serverUrl, callbackPort, headers, transportStrategy }) => { return runProxy(serverUrl, callbackPort, headers, transportStrategy) })