Skip to content

Commit 9fcfd89

Browse files
fix: pass proxy port via URL params when non-default
- Update client to read MCP_PROXY_PORT from URL parameters - Update server to include port in displayed URL when non-default - Update start scripts to pass SERVER_PORT to client - Use DEFAULT_MCP_PROXY_LISTEN_PORT constant instead of magic numbers This fixes the issue where the client couldn't connect to the proxy when SERVER_PORT was set to a non-default value.
1 parent eb5be0d commit 9fcfd89

File tree

3 files changed

+77
-23
lines changed

3 files changed

+77
-23
lines changed

client/bin/start.js

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,29 @@ import { fileURLToPath } from "url";
77
import { randomBytes } from "crypto";
88

99
const __dirname = dirname(fileURLToPath(import.meta.url));
10+
const DEFAULT_MCP_PROXY_LISTEN_PORT = "6277";
1011

1112
function delay(ms) {
1213
return new Promise((resolve) => setTimeout(resolve, ms, true));
1314
}
1415

15-
function getClientUrl(port, authDisabled, sessionToken) {
16+
function getClientUrl(port, authDisabled, sessionToken, serverPort) {
1617
const host = process.env.HOST || "localhost";
1718
const baseUrl = `http://${host}:${port}`;
18-
return authDisabled
19-
? baseUrl
20-
: `${baseUrl}/?MCP_PROXY_AUTH_TOKEN=${sessionToken}`;
19+
20+
if (authDisabled) {
21+
return baseUrl;
22+
}
23+
24+
const params = new URLSearchParams();
25+
params.set("MCP_PROXY_AUTH_TOKEN", sessionToken);
26+
27+
// Add server port if it's not the default
28+
if (serverPort && serverPort !== DEFAULT_MCP_PROXY_LISTEN_PORT) {
29+
params.set("MCP_PROXY_PORT", serverPort);
30+
}
31+
32+
return `${baseUrl}/?${params.toString()}`;
2133
}
2234

2335
async function startDevServer(serverOptions) {
@@ -107,8 +119,14 @@ async function startProdServer(serverOptions) {
107119
}
108120

109121
async function startDevClient(clientOptions) {
110-
const { CLIENT_PORT, authDisabled, sessionToken, abort, cancelled } =
111-
clientOptions;
122+
const {
123+
CLIENT_PORT,
124+
SERVER_PORT,
125+
authDisabled,
126+
sessionToken,
127+
abort,
128+
cancelled,
129+
} = clientOptions;
112130
const clientCommand = "npx";
113131
const host = process.env.HOST || "localhost";
114132
const clientArgs = ["vite", "--port", CLIENT_PORT, "--host", host];
@@ -122,7 +140,12 @@ async function startDevClient(clientOptions) {
122140

123141
// Auto-open browser after vite starts
124142
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
125-
const url = getClientUrl(CLIENT_PORT, authDisabled, sessionToken);
143+
const url = getClientUrl(
144+
CLIENT_PORT,
145+
authDisabled,
146+
sessionToken,
147+
SERVER_PORT,
148+
);
126149

127150
// Give vite time to start before opening browser
128151
setTimeout(() => {
@@ -146,8 +169,14 @@ async function startDevClient(clientOptions) {
146169
}
147170

148171
async function startProdClient(clientOptions) {
149-
const { CLIENT_PORT, authDisabled, sessionToken, abort, cancelled } =
150-
clientOptions;
172+
const {
173+
CLIENT_PORT,
174+
SERVER_PORT,
175+
authDisabled,
176+
sessionToken,
177+
abort,
178+
cancelled,
179+
} = clientOptions;
151180
const inspectorClientPath = resolve(
152181
__dirname,
153182
"../..",
@@ -158,7 +187,12 @@ async function startProdClient(clientOptions) {
158187

159188
// Only auto-open browser if not cancelled
160189
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false" && !cancelled) {
161-
const url = getClientUrl(CLIENT_PORT, authDisabled, sessionToken);
190+
const url = getClientUrl(
191+
CLIENT_PORT,
192+
authDisabled,
193+
sessionToken,
194+
SERVER_PORT,
195+
);
162196
open(url);
163197
}
164198

@@ -210,7 +244,7 @@ async function main() {
210244
}
211245

212246
const CLIENT_PORT = process.env.CLIENT_PORT ?? "6274";
213-
const SERVER_PORT = process.env.SERVER_PORT ?? "6277";
247+
const SERVER_PORT = process.env.SERVER_PORT ?? DEFAULT_MCP_PROXY_LISTEN_PORT;
214248

215249
console.log(
216250
isDev
@@ -255,6 +289,7 @@ async function main() {
255289
try {
256290
const clientOptions = {
257291
CLIENT_PORT,
292+
SERVER_PORT,
258293
authDisabled,
259294
sessionToken,
260295
abort,

client/src/utils/configUtils.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,26 @@ import {
44
DEFAULT_INSPECTOR_CONFIG,
55
} from "@/lib/constants";
66

7+
const getSearchParam = (key: string): string | null => {
8+
try {
9+
const url = new URL(window.location.href);
10+
return url.searchParams.get(key);
11+
} catch {
12+
return null;
13+
}
14+
};
15+
716
export const getMCPProxyAddress = (config: InspectorConfig): string => {
817
const proxyFullAddress = config.MCP_PROXY_FULL_ADDRESS.value as string;
918
if (proxyFullAddress) {
1019
return proxyFullAddress;
1120
}
12-
return `${window.location.protocol}//${window.location.hostname}:${DEFAULT_MCP_PROXY_LISTEN_PORT}`;
21+
22+
// Check for proxy port from query params, fallback to default
23+
const proxyPort =
24+
getSearchParam("MCP_PROXY_PORT") || DEFAULT_MCP_PROXY_LISTEN_PORT;
25+
26+
return `${window.location.protocol}//${window.location.hostname}:${proxyPort}`;
1327
};
1428

1529
export const getMCPServerRequestTimeout = (config: InspectorConfig): number => {
@@ -40,15 +54,6 @@ export const getMCPProxyAuthToken = (
4054
};
4155
};
4256

43-
const getSearchParam = (key: string): string | null => {
44-
try {
45-
const url = new URL(window.location.href);
46-
return url.searchParams.get(key);
47-
} catch {
48-
return null;
49-
}
50-
};
51-
5257
export const getInitialTransportType = ():
5358
| "stdio"
5459
| "sse"

server/src/index.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { findActualExecutable } from "spawn-rx";
2121
import mcpProxy from "./mcpProxy.js";
2222
import { randomUUID, randomBytes, timingSafeEqual } from "node:crypto";
2323

24+
const DEFAULT_MCP_PROXY_LISTEN_PORT = "6277";
2425
const SSE_HEADERS_PASSTHROUGH = ["authorization"];
2526
const STREAMABLE_HTTP_HEADERS_PASSTHROUGH = [
2627
"authorization",
@@ -528,7 +529,10 @@ app.get("/config", originValidationMiddleware, authMiddleware, (req, res) => {
528529
}
529530
});
530531

531-
const PORT = parseInt(process.env.SERVER_PORT || "6277", 10);
532+
const PORT = parseInt(
533+
process.env.SERVER_PORT || DEFAULT_MCP_PROXY_LISTEN_PORT,
534+
10,
535+
);
532536
const HOST = process.env.HOST || "localhost";
533537

534538
const server = app.listen(PORT, HOST);
@@ -543,7 +547,17 @@ server.on("listening", () => {
543547
// Display clickable URL with pre-filled token
544548
const clientPort = process.env.CLIENT_PORT || "6274";
545549
const clientHost = process.env.HOST || "localhost";
546-
const clientUrl = `http://${clientHost}:${clientPort}/?MCP_PROXY_AUTH_TOKEN=${sessionToken}`;
550+
551+
// Build URL with query parameters
552+
const params = new URLSearchParams();
553+
params.set("MCP_PROXY_AUTH_TOKEN", sessionToken);
554+
555+
// Add server port if it's not the default
556+
if (PORT !== parseInt(DEFAULT_MCP_PROXY_LISTEN_PORT, 10)) {
557+
params.set("MCP_PROXY_PORT", PORT.toString());
558+
}
559+
560+
const clientUrl = `http://${clientHost}:${clientPort}/?${params.toString()}`;
547561
console.log(
548562
`\n🔗 Open inspector with token pre-filled:\n ${clientUrl}\n`,
549563
);

0 commit comments

Comments
 (0)