Skip to content

Commit c24d2a9

Browse files
authored
Merge pull request #555 from modelcontextprotocol/fweinberger/fix-proxy-port-config
Fix proxy port configuration for non-default SERVER_PORT
2 parents eb5be0d + 1aea337 commit c24d2a9

File tree

4 files changed

+87
-52
lines changed

4 files changed

+87
-52
lines changed

client/bin/client.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env node
22

3+
import open from "open";
34
import { join, dirname } from "path";
45
import { fileURLToPath } from "url";
56
import handler from "serve-handler";
@@ -42,9 +43,12 @@ const server = http.createServer((request, response) => {
4243
const port = parseInt(process.env.CLIENT_PORT || "6274", 10);
4344
const host = process.env.HOST || "localhost";
4445
server.on("listening", () => {
45-
console.log(
46-
`🔍 MCP Inspector is up and running at http://${host}:${port} 🚀`,
47-
);
46+
const url = process.env.INSPECTOR_URL || `http://${host}:${port}`;
47+
console.log(`\n🚀 MCP Inspector is up and running at:\n ${url}\n`);
48+
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
49+
console.log(`🌐 Opening browser...`);
50+
open(url);
51+
}
4852
});
4953
server.on("error", (err) => {
5054
if (err.message.includes(`EADDRINUSE`)) {

client/bin/start.js

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,24 @@ 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+
const params = new URLSearchParams();
21+
if (serverPort && serverPort !== DEFAULT_MCP_PROXY_LISTEN_PORT) {
22+
params.set("MCP_PROXY_PORT", serverPort);
23+
}
24+
if (!authDisabled) {
25+
params.set("MCP_PROXY_AUTH_TOKEN", sessionToken);
26+
}
27+
return params.size > 0 ? `${baseUrl}/?${params.toString()}` : baseUrl;
2128
}
2229

2330
async function startDevServer(serverOptions) {
@@ -31,8 +38,8 @@ async function startDevServer(serverOptions) {
3138
cwd: resolve(__dirname, "../..", "server"),
3239
env: {
3340
...process.env,
34-
SERVER_PORT: SERVER_PORT,
35-
CLIENT_PORT: CLIENT_PORT,
41+
SERVER_PORT,
42+
CLIENT_PORT,
3643
MCP_PROXY_TOKEN: sessionToken,
3744
MCP_ENV_VARS: JSON.stringify(envVars),
3845
},
@@ -90,8 +97,8 @@ async function startProdServer(serverOptions) {
9097
{
9198
env: {
9299
...process.env,
93-
SERVER_PORT: SERVER_PORT,
94-
CLIENT_PORT: CLIENT_PORT,
100+
SERVER_PORT,
101+
CLIENT_PORT,
95102
MCP_PROXY_TOKEN: sessionToken,
96103
MCP_ENV_VARS: JSON.stringify(envVars),
97104
},
@@ -107,29 +114,40 @@ async function startProdServer(serverOptions) {
107114
}
108115

109116
async function startDevClient(clientOptions) {
110-
const { CLIENT_PORT, authDisabled, sessionToken, abort, cancelled } =
111-
clientOptions;
117+
const {
118+
CLIENT_PORT,
119+
SERVER_PORT,
120+
authDisabled,
121+
sessionToken,
122+
abort,
123+
cancelled,
124+
} = clientOptions;
112125
const clientCommand = "npx";
113126
const host = process.env.HOST || "localhost";
114127
const clientArgs = ["vite", "--port", CLIENT_PORT, "--host", host];
115128

116129
const client = spawn(clientCommand, clientArgs, {
117130
cwd: resolve(__dirname, ".."),
118-
env: { ...process.env, CLIENT_PORT: CLIENT_PORT },
131+
env: { ...process.env, CLIENT_PORT },
119132
signal: abort.signal,
120133
echoOutput: true,
121134
});
122135

123-
// Auto-open browser after vite starts
124-
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
125-
const url = getClientUrl(CLIENT_PORT, authDisabled, sessionToken);
136+
const url = getClientUrl(
137+
CLIENT_PORT,
138+
authDisabled,
139+
sessionToken,
140+
SERVER_PORT,
141+
);
126142

127-
// Give vite time to start before opening browser
128-
setTimeout(() => {
143+
// Give vite time to start before opening or logging the URL
144+
setTimeout(() => {
145+
console.log(`\n🚀 MCP Inspector is up and running at:\n ${url}\n`);
146+
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false") {
147+
console.log("🌐 Opening browser...");
129148
open(url);
130-
console.log(`\n🔗 Opening browser at: ${url}\n`);
131-
}, 3000);
132-
}
149+
}
150+
}, 3000);
133151

134152
await new Promise((resolve) => {
135153
client.subscribe({
@@ -146,8 +164,14 @@ async function startDevClient(clientOptions) {
146164
}
147165

148166
async function startProdClient(clientOptions) {
149-
const { CLIENT_PORT, authDisabled, sessionToken, abort, cancelled } =
150-
clientOptions;
167+
const {
168+
CLIENT_PORT,
169+
SERVER_PORT,
170+
authDisabled,
171+
sessionToken,
172+
abort,
173+
cancelled,
174+
} = clientOptions;
151175
const inspectorClientPath = resolve(
152176
__dirname,
153177
"../..",
@@ -156,14 +180,19 @@ async function startProdClient(clientOptions) {
156180
"client.js",
157181
);
158182

159-
// Only auto-open browser if not cancelled
160-
if (process.env.MCP_AUTO_OPEN_ENABLED !== "false" && !cancelled) {
161-
const url = getClientUrl(CLIENT_PORT, authDisabled, sessionToken);
162-
open(url);
163-
}
183+
const url = getClientUrl(
184+
CLIENT_PORT,
185+
authDisabled,
186+
sessionToken,
187+
SERVER_PORT,
188+
);
164189

165190
await spawnPromise("node", [inspectorClientPath], {
166-
env: { ...process.env, CLIENT_PORT: CLIENT_PORT },
191+
env: {
192+
...process.env,
193+
CLIENT_PORT,
194+
INSPECTOR_URL: url,
195+
},
167196
signal: abort.signal,
168197
echoOutput: true,
169198
});
@@ -210,7 +239,7 @@ async function main() {
210239
}
211240

212241
const CLIENT_PORT = process.env.CLIENT_PORT ?? "6274";
213-
const SERVER_PORT = process.env.SERVER_PORT ?? "6277";
242+
const SERVER_PORT = process.env.SERVER_PORT ?? DEFAULT_MCP_PROXY_LISTEN_PORT;
214243

215244
console.log(
216245
isDev
@@ -255,6 +284,7 @@ async function main() {
255284
try {
256285
const clientOptions = {
257286
CLIENT_PORT,
287+
SERVER_PORT,
258288
authDisabled,
259289
sessionToken,
260290
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: 7 additions & 11 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,24 +529,19 @@ 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);
535539
server.on("listening", () => {
536540
console.log(`⚙️ Proxy server listening on ${HOST}:${PORT}`);
537541
if (!authDisabled) {
538-
console.log(`🔑 Session token: ${sessionToken}`);
539-
console.log(
540-
`Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true to disable auth`,
541-
);
542-
543-
// Display clickable URL with pre-filled token
544-
const clientPort = process.env.CLIENT_PORT || "6274";
545-
const clientHost = process.env.HOST || "localhost";
546-
const clientUrl = `http://${clientHost}:${clientPort}/?MCP_PROXY_AUTH_TOKEN=${sessionToken}`;
547542
console.log(
548-
`\n🔗 Open inspector with token pre-filled:\n ${clientUrl}\n`,
543+
`🔑 Session token: ${sessionToken}\n ` +
544+
`Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true to disable auth`,
549545
);
550546
} else {
551547
console.log(

0 commit comments

Comments
 (0)