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

Method startSingleServer

src/node/services/mcpServerManager.ts:1525–1631  ·  view source on GitHub ↗
(
    name: string,
    info: MCPServerInfo,
    runtime: Runtime,
    projectPath: string,
    workspacePath: string,
    projectSecrets: Record<string, string> | undefined,
    onActivity: () => void
  )

Source from the content-addressed store, hash-verified

1523 }
1524
1525 private async startSingleServer(
1526 name: string,
1527 info: MCPServerInfo,
1528 runtime: Runtime,
1529 projectPath: string,
1530 workspacePath: string,
1531 projectSecrets: Record<string, string> | undefined,
1532 onActivity: () => void
1533 ): Promise<MCPServerInstance | null> {
1534 let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
1535 const abortController = new AbortController();
1536 let abortCleanupPromise: Promise<void> | null = null;
1537
1538 const registerAbortCleanup = (cleanupPromise: Promise<void>) => {
1539 abortCleanupPromise ??= cleanupPromise;
1540 };
1541
1542 let didTimeout = false;
1543 const keepPendingAfterTimeout = () => new Promise<MCPServerInstance | null>(() => undefined);
1544
1545 const startup = this.startSingleServerImpl(
1546 name,
1547 info,
1548 runtime,
1549 projectPath,
1550 workspacePath,
1551 projectSecrets,
1552 onActivity,
1553 abortController.signal,
1554 registerAbortCleanup
1555 ).then(
1556 (instance) => (didTimeout ? keepPendingAfterTimeout() : instance),
1557 (error) => {
1558 if (didTimeout) {
1559 return keepPendingAfterTimeout();
1560 }
1561 throw error;
1562 }
1563 );
1564
1565 const timeout = new Promise<never>((_resolve, reject) => {
1566 timeoutHandle = setTimeout(() => {
1567 didTimeout = true;
1568
1569 // Promise.race does not cancel the losing startup branch automatically.
1570 // Abort in-flight startup so stdio processes and partial MCP clients are cleaned up.
1571 abortController.abort();
1572
1573 const timeoutError = new MCPStartupTimeoutError(name, MCP_STARTUP_TIMEOUT_MS);
1574 if (!abortCleanupPromise) {
1575 reject(timeoutError);
1576 return;
1577 }
1578
1579 const cleanupWait = abortCleanupPromise.catch((error: unknown) => {
1580 log.debug("[MCP] Error waiting for startup cleanup", {
1581 name,
1582 error: getErrorMessage(error),

Callers 2

startServersMethod · 0.95

Calls 6

startSingleServerImplMethod · 0.95
getErrorMessageFunction · 0.90
rejectFunction · 0.85
debugMethod · 0.80
resolveFunction · 0.70
abortMethod · 0.65

Tested by

no test coverage detected