Go full lazy with http transport
This also means we need to default to sse-first
This commit is contained in:
parent
1908c203ff
commit
02305b3d1c
3 changed files with 31 additions and 39 deletions
|
@ -31,7 +31,7 @@ async function runClient(
|
|||
serverUrl: string,
|
||||
callbackPort: number,
|
||||
headers: Record<string, string>,
|
||||
transportStrategy: TransportStrategy = 'http-first',
|
||||
transportStrategy: TransportStrategy = 'sse-first',
|
||||
) {
|
||||
// Set up event emitter for auth flow
|
||||
const events = new EventEmitter()
|
||||
|
@ -66,10 +66,10 @@ async function runClient(
|
|||
// Define an auth initializer function
|
||||
const authInitializer = async () => {
|
||||
const authState = await authCoordinator.initializeAuth()
|
||||
|
||||
|
||||
// Store server in outer scope for cleanup
|
||||
server = authState.server
|
||||
|
||||
|
||||
// If auth was completed by another instance, just log that we'll use the auth from disk
|
||||
if (authState.skipBrowserAuth) {
|
||||
log('Authentication was completed by another instance - will use tokens from disk...')
|
||||
|
@ -77,23 +77,16 @@ async function runClient(
|
|||
// so we're slightly too early
|
||||
await new Promise((res) => setTimeout(res, 1_000))
|
||||
}
|
||||
|
||||
return {
|
||||
waitForAuthCode: authState.waitForAuthCode,
|
||||
skipBrowserAuth: authState.skipBrowserAuth
|
||||
|
||||
return {
|
||||
waitForAuthCode: authState.waitForAuthCode,
|
||||
skipBrowserAuth: authState.skipBrowserAuth,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// Connect to remote server with lazy authentication
|
||||
const transport = await connectToRemoteServer(
|
||||
client,
|
||||
serverUrl,
|
||||
authProvider,
|
||||
headers,
|
||||
authInitializer,
|
||||
transportStrategy,
|
||||
)
|
||||
const transport = await connectToRemoteServer(client, serverUrl, authProvider, headers, authInitializer, transportStrategy)
|
||||
|
||||
// Set up message and error handlers
|
||||
transport.onmessage = (message) => {
|
||||
|
|
|
@ -93,12 +93,12 @@ export type AuthInitializer = () => Promise<{
|
|||
* @returns The connected transport
|
||||
*/
|
||||
export async function connectToRemoteServer(
|
||||
client: Client,
|
||||
client: Client | null,
|
||||
serverUrl: string,
|
||||
authProvider: OAuthClientProvider,
|
||||
headers: Record<string, string>,
|
||||
authInitializer: AuthInitializer,
|
||||
transportStrategy: TransportStrategy = 'http-first',
|
||||
transportStrategy: TransportStrategy = 'sse-first',
|
||||
recursionReasons: Set<string> = new Set(),
|
||||
): Promise<Transport> {
|
||||
log(`[${pid}] Connecting to remote server: ${serverUrl}`)
|
||||
|
@ -140,7 +140,11 @@ export async function connectToRemoteServer(
|
|||
})
|
||||
|
||||
try {
|
||||
await client.connect(transport)
|
||||
if (client) {
|
||||
await client.connect(transport)
|
||||
} else {
|
||||
await transport.start()
|
||||
}
|
||||
log(`Connected to remote server using ${transport.constructor.name}`)
|
||||
|
||||
return transport
|
||||
|
@ -380,7 +384,7 @@ export async function parseCommandLineArgs(args: string[], defaultPort: number,
|
|||
const allowHttp = args.includes('--allow-http')
|
||||
|
||||
// Parse transport strategy
|
||||
let transportStrategy: TransportStrategy = 'http-first' // Default
|
||||
let transportStrategy: TransportStrategy = 'sse-first' // Default
|
||||
const transportIndex = args.indexOf('--transport')
|
||||
if (transportIndex !== -1 && transportIndex < args.length - 1) {
|
||||
const strategy = args[transportIndex + 1]
|
||||
|
|
33
src/proxy.ts
33
src/proxy.ts
|
@ -23,12 +23,16 @@ import {
|
|||
} from './lib/utils'
|
||||
import { NodeOAuthClientProvider } from './lib/node-oauth-client-provider'
|
||||
import { createLazyAuthCoordinator } from './lib/coordination'
|
||||
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
||||
|
||||
/**
|
||||
* Main function to run the proxy
|
||||
*/
|
||||
async function runProxy(serverUrl: string, callbackPort: number, headers: Record<string, string>, transportStrategy: TransportStrategy = 'http-first') {
|
||||
async function runProxy(
|
||||
serverUrl: string,
|
||||
callbackPort: number,
|
||||
headers: Record<string, string>,
|
||||
transportStrategy: TransportStrategy = 'sse-first',
|
||||
) {
|
||||
// Set up event emitter for auth flow
|
||||
const events = new EventEmitter()
|
||||
|
||||
|
@ -54,10 +58,10 @@ async function runProxy(serverUrl: string, callbackPort: number, headers: Record
|
|||
// Define an auth initializer function
|
||||
const authInitializer = async () => {
|
||||
const authState = await authCoordinator.initializeAuth()
|
||||
|
||||
|
||||
// Store server in outer scope for cleanup
|
||||
server = authState.server
|
||||
|
||||
|
||||
// If auth was completed by another instance, just log that we'll use the auth from disk
|
||||
if (authState.skipBrowserAuth) {
|
||||
log('Authentication was completed by another instance - will use tokens from disk')
|
||||
|
@ -65,25 +69,16 @@ async function runProxy(serverUrl: string, callbackPort: number, headers: Record
|
|||
// so we're slightly too early
|
||||
await new Promise((res) => setTimeout(res, 1_000))
|
||||
}
|
||||
|
||||
return {
|
||||
waitForAuthCode: authState.waitForAuthCode,
|
||||
skipBrowserAuth: authState.skipBrowserAuth
|
||||
|
||||
return {
|
||||
waitForAuthCode: authState.waitForAuthCode,
|
||||
skipBrowserAuth: authState.skipBrowserAuth,
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const client = new Client(
|
||||
{
|
||||
name: 'mcp-remote',
|
||||
version: MCP_REMOTE_VERSION,
|
||||
},
|
||||
{
|
||||
capabilities: {},
|
||||
},
|
||||
)
|
||||
// Connect to remote server with lazy authentication
|
||||
const remoteTransport = await connectToRemoteServer(client, serverUrl, authProvider, headers, authInitializer, transportStrategy)
|
||||
const remoteTransport = await connectToRemoteServer(null, serverUrl, authProvider, headers, authInitializer, transportStrategy)
|
||||
|
||||
// Set up bidirectional proxy between local and remote transports
|
||||
mcpProxy({
|
||||
|
@ -94,7 +89,7 @@ async function runProxy(serverUrl: string, callbackPort: number, headers: Record
|
|||
// Start the local STDIO server
|
||||
await localTransport.start()
|
||||
log('Local STDIO server running')
|
||||
log('Proxy established successfully between local STDIO and remote SSE')
|
||||
log(`Proxy established successfully between local STDIO and remote ${remoteTransport.constructor.name}`)
|
||||
log('Press Ctrl+C to exit')
|
||||
|
||||
// Setup cleanup handler
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue