@@ -7,17 +7,24 @@ import { fileURLToPath } from "url";
7
7
import { randomBytes } from "crypto" ;
8
8
9
9
const __dirname = dirname ( fileURLToPath ( import . meta. url ) ) ;
10
+ const DEFAULT_MCP_PROXY_LISTEN_PORT = "6277" ;
10
11
11
12
function delay ( ms ) {
12
13
return new Promise ( ( resolve ) => setTimeout ( resolve , ms , true ) ) ;
13
14
}
14
15
15
- function getClientUrl ( port , authDisabled , sessionToken ) {
16
+ function getClientUrl ( port , authDisabled , sessionToken , serverPort ) {
16
17
const host = process . env . HOST || "localhost" ;
17
18
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 ;
21
28
}
22
29
23
30
async function startDevServer ( serverOptions ) {
@@ -31,8 +38,8 @@ async function startDevServer(serverOptions) {
31
38
cwd : resolve ( __dirname , "../.." , "server" ) ,
32
39
env : {
33
40
...process . env ,
34
- SERVER_PORT : SERVER_PORT ,
35
- CLIENT_PORT : CLIENT_PORT ,
41
+ SERVER_PORT ,
42
+ CLIENT_PORT ,
36
43
MCP_PROXY_TOKEN : sessionToken ,
37
44
MCP_ENV_VARS : JSON . stringify ( envVars ) ,
38
45
} ,
@@ -90,8 +97,8 @@ async function startProdServer(serverOptions) {
90
97
{
91
98
env : {
92
99
...process . env ,
93
- SERVER_PORT : SERVER_PORT ,
94
- CLIENT_PORT : CLIENT_PORT ,
100
+ SERVER_PORT ,
101
+ CLIENT_PORT ,
95
102
MCP_PROXY_TOKEN : sessionToken ,
96
103
MCP_ENV_VARS : JSON . stringify ( envVars ) ,
97
104
} ,
@@ -107,29 +114,40 @@ async function startProdServer(serverOptions) {
107
114
}
108
115
109
116
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 ;
112
125
const clientCommand = "npx" ;
113
126
const host = process . env . HOST || "localhost" ;
114
127
const clientArgs = [ "vite" , "--port" , CLIENT_PORT , "--host" , host ] ;
115
128
116
129
const client = spawn ( clientCommand , clientArgs , {
117
130
cwd : resolve ( __dirname , ".." ) ,
118
- env : { ...process . env , CLIENT_PORT : CLIENT_PORT } ,
131
+ env : { ...process . env , CLIENT_PORT } ,
119
132
signal : abort . signal ,
120
133
echoOutput : true ,
121
134
} ) ;
122
135
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
+ ) ;
126
142
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..." ) ;
129
148
open ( url ) ;
130
- console . log ( `\n🔗 Opening browser at: ${ url } \n` ) ;
131
- } , 3000 ) ;
132
- }
149
+ }
150
+ } , 3000 ) ;
133
151
134
152
await new Promise ( ( resolve ) => {
135
153
client . subscribe ( {
@@ -146,8 +164,14 @@ async function startDevClient(clientOptions) {
146
164
}
147
165
148
166
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 ;
151
175
const inspectorClientPath = resolve (
152
176
__dirname ,
153
177
"../.." ,
@@ -156,14 +180,19 @@ async function startProdClient(clientOptions) {
156
180
"client.js" ,
157
181
) ;
158
182
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
+ ) ;
164
189
165
190
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
+ } ,
167
196
signal : abort . signal ,
168
197
echoOutput : true ,
169
198
} ) ;
@@ -210,7 +239,7 @@ async function main() {
210
239
}
211
240
212
241
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 ;
214
243
215
244
console . log (
216
245
isDev
@@ -255,6 +284,7 @@ async function main() {
255
284
try {
256
285
const clientOptions = {
257
286
CLIENT_PORT ,
287
+ SERVER_PORT ,
258
288
authDisabled,
259
289
sessionToken,
260
290
abort,
0 commit comments