MCPcopy
hub / github.com/coder/mux / startServer

Method startServer

src/node/services/serverService.ts:348–463  ·  view source on GitHub ↗

* Start the HTTP/WS API server. * * @throws Error if a server is already running (check lockfile first)

(options: StartServerOptions)

Source from the content-addressed store, hash-verified

346 * @throws Error if a server is already running (check lockfile first)
347 */
348 async startServer(options: StartServerOptions): Promise<ServerInfo> {
349 if (this.server) {
350 throw new Error("Server already running in this process");
351 }
352
353 // Create lockfile instance for checking - don't store yet
354 const lockfile = new ServerLockfile(options.muxHome);
355
356 // Check for existing server (another process)
357 const existing = await lockfile.read();
358 if (existing) {
359 throw new Error(
360 `Another mux server is already running at ${existing.baseUrl} (PID: ${existing.pid})`
361 );
362 }
363
364 const bindHost =
365 typeof options.host === "string" && options.host.trim() ? options.host.trim() : "127.0.0.1";
366
367 this.apiAuthToken = options.authToken;
368
369 // Resolve the static assets directory (dist/) that contains index.html.
370 // Non-bundled (Electron): __dirname is dist/node/services/, so ../.. reaches dist/.
371 // Bundled (Docker): __dirname is dist/runtime/, so .. reaches dist/.
372 const staticDirCandidates = [path.join(__dirname, "../.."), path.join(__dirname, "..")];
373
374 let staticDir: string | undefined;
375 if (options.serveStatic) {
376 for (const candidate of staticDirCandidates) {
377 try {
378 await fs.access(path.join(candidate, "index.html"));
379 staticDir = candidate;
380 break;
381 } catch {
382 // Try the next candidate.
383 }
384 }
385
386 if (!staticDir) {
387 log.warn(
388 `API server static UI requested, but index.html is missing near ${__dirname}. Disabling.`
389 );
390 }
391 }
392 const serveStatic = options.serveStatic === true && staticDir !== undefined;
393
394 // Non-CLI starts (desktop/browser mode) do not parse CLI flags, so allow an
395 // explicit env override for TLS-terminating proxies that rewrite forwarded proto.
396 const allowHttpOrigin = options.allowHttpOrigin ?? resolveAllowHttpOriginEnvFlag();
397
398 const serverOptions: OrpcServerOptions = {
399 host: bindHost,
400 port: options.port ?? 0,
401 context: options.context,
402 authToken: options.authToken,
403 router: options.router,
404 desktopBridgeServer: options.context.desktopBridgeServer,
405 serveStatic,

Callers 4

loadServicesFunction · 0.80
mainFunction · 0.80
routerFunction · 0.80

Calls 11

readMethod · 0.95
acquireMethod · 0.95
createOrpcServerFunction · 0.90
computeNetworkBaseUrlsFunction · 0.85
getMdnsServiceNameMethod · 0.80
isLoopbackHostFunction · 0.70
closeMethod · 0.65
startMethod · 0.45

Tested by

no test coverage detected