diff --git a/README.md b/README.md index ded8937..c9cdfc7 100644 --- a/README.md +++ b/README.md @@ -77,16 +77,6 @@ To bypass authentication, or to emit custom headers on all requests to your remo ] ``` -* To force `mcp-remote` to ignore any existing access tokens and begin the authorization flow anew, pass `--clean`. - -```json - "args": [ - "mcp-remote", - "https://remote.mcp.server/sse", - "--clean" - ] -``` - * 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. ```json @@ -211,4 +201,4 @@ Run the following on the command line (not from an MCP server): npx -p mcp-remote@latest mcp-remote-client https://remote.mcp.server/sse ``` -This will run through the entire authorization flow and attempt to list the tools & resources at the remote URL. Pair this with `--clean` or after running `rm -rf ~/.mcp-auth` to see if stale credentials are your problem, otherwise hopefully the issue will be more obvious in these logs than those in your MCP client. +This will run through the entire authorization flow and attempt to list the tools & resources at the remote URL. Try this after running `rm -rf ~/.mcp-auth` to see if stale credentials are your problem, otherwise hopefully the issue will be more obvious in these logs than those in your MCP client. diff --git a/package.json b/package.json index f586b76..e10cf38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mcp-remote", - "version": "0.0.18", + "version": "0.0.19", "description": "Remote proxy for Model Context Protocol, allowing local-only clients to connect to remote servers using oAuth", "keywords": [ "mcp", diff --git a/src/client.ts b/src/client.ts index 9a4b7c4..d620884 100644 --- a/src/client.ts +++ b/src/client.ts @@ -4,10 +4,7 @@ * MCP Client with OAuth support * A command-line client that connects to an MCP server using SSE with OAuth authentication. * - * Run with: npx tsx client.ts [--clean] https://example.remote/server [callback-port] - * - * Options: - * --clean: Deletes stored configuration before reading, ensuring a fresh session + * Run with: npx tsx client.ts https://example.remote/server [callback-port] * * If callback-port is not specified, an available port will be automatically selected. */ @@ -24,7 +21,7 @@ import { coordinateAuth } from './lib/coordination' /** * Main function to run the client */ -async function runClient(serverUrl: string, callbackPort: number, headers: Record, clean: boolean = false) { +async function runClient(serverUrl: string, callbackPort: number, headers: Record) { // Set up event emitter for auth flow const events = new EventEmitter() @@ -39,7 +36,6 @@ async function runClient(serverUrl: string, callbackPort: number, headers: Recor serverUrl, callbackPort, clientName: 'MCP CLI Client', - clean, }) // If auth was completed by another instance, just log that we'll use the auth from disk @@ -159,9 +155,9 @@ async function runClient(serverUrl: string, callbackPort: number, headers: Recor } // Parse command-line arguments and run the client -parseCommandLineArgs(process.argv.slice(2), 3333, 'Usage: npx tsx client.ts [--clean] [callback-port]') - .then(({ serverUrl, callbackPort, clean, headers }) => { - return runClient(serverUrl, callbackPort, headers, clean) +parseCommandLineArgs(process.argv.slice(2), 3333, 'Usage: npx tsx client.ts [callback-port]') + .then(({ serverUrl, callbackPort, headers }) => { + return runClient(serverUrl, callbackPort, headers) }) .catch((error) => { console.error('Fatal error:', error) diff --git a/src/lib/mcp-auth-config.ts b/src/lib/mcp-auth-config.ts index fce4219..1286b03 100644 --- a/src/lib/mcp-auth-config.ts +++ b/src/lib/mcp-auth-config.ts @@ -23,11 +23,6 @@ import { log, MCP_REMOTE_VERSION } from './utils' * All JSON files are stored with 2-space indentation for readability. */ -/** - * Known configuration file names that might need to be cleaned - */ -export const knownConfigFiles = ['client_info.json', 'tokens.json', 'code_verifier.txt', 'lock.json'] - /** * Lockfile data structure */ @@ -82,17 +77,6 @@ export async function deleteLockfile(serverUrlHash: string): Promise { await deleteConfigFile(serverUrlHash, 'lock.json') } -/** - * Deletes all known configuration files for a specific server - * @param serverUrlHash The hash of the server URL - */ -export async function cleanServerConfig(serverUrlHash: string): Promise { - log(`Cleaning configuration files for server: ${serverUrlHash}`) - for (const filename of knownConfigFiles) { - await deleteConfigFile(serverUrlHash, filename) - } -} - /** * Gets the configuration directory path * @returns The path to the configuration directory @@ -149,24 +133,12 @@ export async function deleteConfigFile(serverUrlHash: string, filename: string): * @param serverUrlHash The hash of the server URL * @param filename The name of the file to read * @param schema The schema to validate against - * @param clean Whether to clean (delete) before reading * @returns The parsed file content or undefined if the file doesn't exist */ -export async function readJsonFile( - serverUrlHash: string, - filename: string, - schema: any, - clean: boolean = false, -): Promise { +export async function readJsonFile(serverUrlHash: string, filename: string, schema: any): Promise { try { await ensureConfigDir() - // If clean flag is set, delete the file before trying to read it - if (clean) { - await deleteConfigFile(serverUrlHash, filename) - return undefined - } - const filePath = getConfigFilePath(serverUrlHash, filename) const content = await fs.readFile(filePath, 'utf-8') const result = await schema.parseAsync(JSON.parse(content)) @@ -204,24 +176,11 @@ export async function writeJsonFile(serverUrlHash: string, filename: string, dat * @param serverUrlHash The hash of the server URL * @param filename The name of the file to read * @param errorMessage Optional custom error message - * @param clean Whether to clean (delete) before reading * @returns The file content as a string */ -export async function readTextFile( - serverUrlHash: string, - filename: string, - errorMessage?: string, - clean: boolean = false, -): Promise { +export async function readTextFile(serverUrlHash: string, filename: string, errorMessage?: string): Promise { try { await ensureConfigDir() - - // If clean flag is set, delete the file before trying to read it - if (clean) { - await deleteConfigFile(serverUrlHash, filename) - throw new Error('File deleted due to clean flag') - } - const filePath = getConfigFilePath(serverUrlHash, filename) return await fs.readFile(filePath, 'utf-8') } catch (error) { diff --git a/src/lib/node-oauth-client-provider.ts b/src/lib/node-oauth-client-provider.ts index c02ce97..d6f2955 100644 --- a/src/lib/node-oauth-client-provider.ts +++ b/src/lib/node-oauth-client-provider.ts @@ -8,7 +8,7 @@ import { OAuthTokensSchema, } from '@modelcontextprotocol/sdk/shared/auth.js' import type { OAuthProviderOptions } from './types' -import { readJsonFile, writeJsonFile, readTextFile, writeTextFile, cleanServerConfig } from './mcp-auth-config' +import { readJsonFile, writeJsonFile, readTextFile, writeTextFile } from './mcp-auth-config' import { getServerUrlHash, log } from './utils' /** @@ -30,13 +30,6 @@ export class NodeOAuthClientProvider implements OAuthClientProvider { this.callbackPath = options.callbackPath || '/oauth/callback' this.clientName = options.clientName || 'MCP CLI Client' this.clientUri = options.clientUri || 'https://github.com/modelcontextprotocol/mcp-cli' - - // If clean flag is set, proactively clean all config files for this server - if (options.clean) { - cleanServerConfig(this.serverUrlHash).catch((err) => { - log('Error cleaning server config:', err) - }) - } } get redirectUrl(): string { @@ -60,7 +53,7 @@ export class NodeOAuthClientProvider implements OAuthClientProvider { */ async clientInformation(): Promise { // log('Reading client info') - return readJsonFile(this.serverUrlHash, 'client_info.json', OAuthClientInformationSchema, this.options.clean) + return readJsonFile(this.serverUrlHash, 'client_info.json', OAuthClientInformationSchema) } /** @@ -79,7 +72,7 @@ export class NodeOAuthClientProvider implements OAuthClientProvider { async tokens(): Promise { // log('Reading tokens') // console.log(new Error().stack) - return readJsonFile(this.serverUrlHash, 'tokens.json', OAuthTokensSchema, this.options.clean) + return readJsonFile(this.serverUrlHash, 'tokens.json', OAuthTokensSchema) } /** @@ -120,6 +113,6 @@ export class NodeOAuthClientProvider implements OAuthClientProvider { */ async codeVerifier(): Promise { // log('Reading code verifier') - return await readTextFile(this.serverUrlHash, 'code_verifier.txt', 'No code verifier saved for session', this.options.clean) + return await readTextFile(this.serverUrlHash, 'code_verifier.txt', 'No code verifier saved for session') } } diff --git a/src/lib/types.ts b/src/lib/types.ts index e719905..188fccb 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -16,8 +16,6 @@ export interface OAuthProviderOptions { clientName?: string /** Client URI to use for OAuth registration */ clientUri?: string - /** Whether to clean stored configuration before reading */ - clean?: boolean } /** diff --git a/src/lib/utils.ts b/src/lib/utils.ts index b53d3b0..07dd579 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -275,18 +275,9 @@ export async function findAvailablePort(preferredPort?: number): Promise * @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, clean flag, and headers + * @returns A promise that resolves to an object with parsed serverUrl, callbackPort and headers */ export async function parseCommandLineArgs(args: string[], defaultPort: number, usage: string) { - // Check for --clean flag - const cleanIndex = args.indexOf('--clean') - const clean = cleanIndex !== -1 - - // Remove the flag from args if it exists - if (clean) { - args.splice(cleanIndex, 1) - } - // Process headers const headers: Record = {} args.forEach((arg, i) => { @@ -327,10 +318,6 @@ export async function parseCommandLineArgs(args: string[], defaultPort: number, log(`Using automatically selected callback port: ${callbackPort}`) } - if (clean) { - log('Clean mode enabled: config files will be reset before reading') - } - if (Object.keys(headers).length > 0) { log(`Using custom headers: ${JSON.stringify(headers)}`) } @@ -350,7 +337,7 @@ export async function parseCommandLineArgs(args: string[], defaultPort: number, }) } - return { serverUrl, callbackPort, clean, headers } + return { serverUrl, callbackPort, headers } } /** diff --git a/src/proxy.ts b/src/proxy.ts index f9a415f..9fd87d1 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -4,10 +4,7 @@ * MCP Proxy with OAuth support * A bidirectional proxy between a local STDIO MCP server and a remote SSE server with OAuth authentication. * - * Run with: npx tsx proxy.ts [--clean] https://example.remote/server [callback-port] - * - * Options: - * --clean: Deletes stored configuration before reading, ensuring a fresh session + * Run with: npx tsx proxy.ts https://example.remote/server [callback-port] * * If callback-port is not specified, an available port will be automatically selected. */ @@ -21,7 +18,7 @@ import { coordinateAuth } from './lib/coordination' /** * Main function to run the proxy */ -async function runProxy(serverUrl: string, callbackPort: number, headers: Record, clean: boolean = false) { +async function runProxy(serverUrl: string, callbackPort: number, headers: Record) { // Set up event emitter for auth flow const events = new EventEmitter() @@ -36,7 +33,6 @@ async function runProxy(serverUrl: string, callbackPort: number, headers: Record serverUrl, callbackPort, clientName: 'MCP CLI Proxy', - clean, }) // If auth was completed by another instance, just log that we'll use the auth from disk @@ -103,9 +99,9 @@ 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 [--clean] [callback-port]') - .then(({ serverUrl, callbackPort, clean, headers }) => { - return runProxy(serverUrl, callbackPort, headers, clean) +parseCommandLineArgs(process.argv.slice(2), 3334, 'Usage: npx tsx proxy.ts [callback-port]') + .then(({ serverUrl, callbackPort, headers }) => { + return runProxy(serverUrl, callbackPort, headers) }) .catch((error) => { log('Fatal error:', error)