Merge c0f7c49d05
into 7eecc9ca3f
This commit is contained in:
commit
8e3d19e5b6
6 changed files with 32 additions and 7 deletions
11
README.md
11
README.md
|
@ -104,6 +104,17 @@ To bypass authentication, or to emit custom headers on all requests to your remo
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* To change which host `mcp-remote` registers as the OAuth callback URL (by default `localhost`), add the `--host` flag.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"args": [
|
||||||
|
"mcp-remote",
|
||||||
|
"https://remote.mcp.server/sse",
|
||||||
|
"--host",
|
||||||
|
"127.0.0.1"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
* To allow HTTP connections in trusted private networks, add the `--allow-http` flag. Note: This should only be used in secure private networks where traffic cannot be intercepted.
|
* To allow HTTP connections in trusted private networks, add the `--allow-http` flag. Note: This should only be used in secure private networks where traffic cannot be intercepted.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|
|
@ -32,6 +32,7 @@ async function runClient(
|
||||||
callbackPort: number,
|
callbackPort: number,
|
||||||
headers: Record<string, string>,
|
headers: Record<string, string>,
|
||||||
transportStrategy: TransportStrategy = 'http-first',
|
transportStrategy: TransportStrategy = 'http-first',
|
||||||
|
host: string,
|
||||||
) {
|
) {
|
||||||
// Set up event emitter for auth flow
|
// Set up event emitter for auth flow
|
||||||
const events = new EventEmitter()
|
const events = new EventEmitter()
|
||||||
|
@ -46,6 +47,7 @@ async function runClient(
|
||||||
const authProvider = new NodeOAuthClientProvider({
|
const authProvider = new NodeOAuthClientProvider({
|
||||||
serverUrl,
|
serverUrl,
|
||||||
callbackPort,
|
callbackPort,
|
||||||
|
host,
|
||||||
clientName: 'MCP CLI Client',
|
clientName: 'MCP CLI Client',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -152,8 +154,8 @@ async function runClient(
|
||||||
|
|
||||||
// Parse command-line arguments and run the client
|
// Parse command-line arguments and run the client
|
||||||
parseCommandLineArgs(process.argv.slice(2), 'Usage: npx tsx client.ts <https://server-url> [callback-port]')
|
parseCommandLineArgs(process.argv.slice(2), 'Usage: npx tsx client.ts <https://server-url> [callback-port]')
|
||||||
.then(({ serverUrl, callbackPort, headers, transportStrategy }) => {
|
.then(({ serverUrl, callbackPort, headers, transportStrategy, host }) => {
|
||||||
return runClient(serverUrl, callbackPort, headers, transportStrategy)
|
return runClient(serverUrl, callbackPort, headers, transportStrategy, host)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Fatal error:', error)
|
console.error('Fatal error:', error)
|
||||||
|
|
|
@ -36,7 +36,7 @@ export class NodeOAuthClientProvider implements OAuthClientProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
get redirectUrl(): string {
|
get redirectUrl(): string {
|
||||||
return `http://localhost:${this.options.callbackPort}${this.callbackPath}`
|
return `http://${this.options.host}:${this.options.callbackPort}${this.callbackPath}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
get clientMetadata() {
|
get clientMetadata() {
|
||||||
|
|
|
@ -8,6 +8,8 @@ export interface OAuthProviderOptions {
|
||||||
serverUrl: string
|
serverUrl: string
|
||||||
/** Port for the OAuth callback server */
|
/** Port for the OAuth callback server */
|
||||||
callbackPort: number
|
callbackPort: number
|
||||||
|
/** Desired hostname for the OAuth callback server */
|
||||||
|
host: string
|
||||||
/** Path for the OAuth callback endpoint */
|
/** Path for the OAuth callback endpoint */
|
||||||
callbackPath?: string
|
callbackPath?: string
|
||||||
/** Directory to store OAuth credentials */
|
/** Directory to store OAuth credentials */
|
||||||
|
|
|
@ -361,7 +361,7 @@ async function findExistingClientPort(serverUrlHash: string): Promise<number | u
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const localhostRedirectUri = clientInfo.redirect_uris.map((uri) => new URL(uri)).find(({ hostname }) => hostname === 'localhost')
|
const localhostRedirectUri = clientInfo.redirect_uris.map((uri) => new URL(uri)).find(({ hostname }) => hostname === 'localhost' || hostname === '127.0.0.1')
|
||||||
if (!localhostRedirectUri) {
|
if (!localhostRedirectUri) {
|
||||||
throw new Error('Cannot find localhost callback URI from existing client information')
|
throw new Error('Cannot find localhost callback URI from existing client information')
|
||||||
}
|
}
|
||||||
|
@ -449,6 +449,14 @@ export async function parseCommandLineArgs(args: string[], usage: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse host
|
||||||
|
let host = 'localhost' // Default
|
||||||
|
const hostIndex = args.indexOf('--host')
|
||||||
|
if (hostIndex !== -1 && hostIndex < args.length - 1) {
|
||||||
|
host = args[hostIndex + 1]
|
||||||
|
log(`Using callback hostname: ${host}`)
|
||||||
|
}
|
||||||
|
|
||||||
if (!serverUrl) {
|
if (!serverUrl) {
|
||||||
log(usage)
|
log(usage)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
|
@ -505,7 +513,7 @@ export async function parseCommandLineArgs(args: string[], usage: string) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return { serverUrl, callbackPort, headers, transportStrategy }
|
return { serverUrl, callbackPort, headers, transportStrategy, host }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -32,6 +32,7 @@ async function runProxy(
|
||||||
callbackPort: number,
|
callbackPort: number,
|
||||||
headers: Record<string, string>,
|
headers: Record<string, string>,
|
||||||
transportStrategy: TransportStrategy = 'http-first',
|
transportStrategy: TransportStrategy = 'http-first',
|
||||||
|
host: string,
|
||||||
) {
|
) {
|
||||||
// Set up event emitter for auth flow
|
// Set up event emitter for auth flow
|
||||||
const events = new EventEmitter()
|
const events = new EventEmitter()
|
||||||
|
@ -46,6 +47,7 @@ async function runProxy(
|
||||||
const authProvider = new NodeOAuthClientProvider({
|
const authProvider = new NodeOAuthClientProvider({
|
||||||
serverUrl,
|
serverUrl,
|
||||||
callbackPort,
|
callbackPort,
|
||||||
|
host,
|
||||||
clientName: 'MCP CLI Proxy',
|
clientName: 'MCP CLI Proxy',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -136,8 +138,8 @@ to the CA certificate file. If using claude_desktop_config.json, this might look
|
||||||
|
|
||||||
// Parse command-line arguments and run the proxy
|
// Parse command-line arguments and run the proxy
|
||||||
parseCommandLineArgs(process.argv.slice(2), 'Usage: npx tsx proxy.ts <https://server-url> [callback-port]')
|
parseCommandLineArgs(process.argv.slice(2), 'Usage: npx tsx proxy.ts <https://server-url> [callback-port]')
|
||||||
.then(({ serverUrl, callbackPort, headers, transportStrategy }) => {
|
.then(({ serverUrl, callbackPort, headers, transportStrategy, host }) => {
|
||||||
return runProxy(serverUrl, callbackPort, headers, transportStrategy)
|
return runProxy(serverUrl, callbackPort, headers, transportStrategy, host)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
log('Fatal error:', error)
|
log('Fatal error:', error)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue