upstash/context7 · warning
Port ${port} is in use, trying port ${port + 1}...
Error message
Port ${port} is in use, trying port ${port + 1}... What it means
Emitted by the context7 MCP server's HTTP transport when app.listen(port) fails with EADDRINUSE. The server then retries port+1, up to maxAttempts=10 consecutive ports above initialPort (CLI_PORT ?? DEFAULT_PORT=3000). If attempts are exhausted or the error is not EADDRINUSE, it logs 'Failed to start server' and exits 1. The 'listening' callback prints the port actually bound.
Source
Thrown at packages/mcp/src/index.ts:540
}
res.type("text/plain").send(OPENAI_APPS_CHALLENGE_TOKEN);
}
);
// Catch-all 404 handler - must be after all other routes
app.use((_req: express.Request, res: express.Response) => {
res.status(404).json({
error: "not_found",
message: "Endpoint not found. Use /mcp for MCP protocol communication.",
});
});
const startServer = (port: number, maxAttempts = 10) => {
const httpServer = app.listen(port);
httpServer.once("error", (err: NodeJS.ErrnoException) => {
if (err.code === "EADDRINUSE" && port < initialPort + maxAttempts) {
console.warn(`Port ${port} is in use, trying port ${port + 1}...`);
startServer(port + 1, maxAttempts);
} else {
console.error(`Failed to start server: ${err.message}`);
process.exit(1);
}
});
httpServer.once("listening", () => {
console.error(
`Context7 Documentation MCP Server v${SERVER_VERSION} running on HTTP at http://localhost:${port}/mcp`
);
});
};
startServer(initialPort);
} else {
stdioApiKey = cliOptions.apiKey || process.env.CONTEXT7_API_KEY;
stdioSessionId = randomUUID();View on GitHub (pinned to c3248289c2)
Solutions
- Let it self-heal: it retries and the startup line 'running on HTTP at http://localhost:<port>/mcp' shows the final port — use that port in the client config
- Free the occupied port: lsof -ti :3000 | xargs kill -9, or stop the dev server using it
- Pass a known-free port explicitly: context7-mcp --http --port 3900
- If you need a fixed port (a client config already points at it), ensure nothing else binds it before launch
Example fix
# before — port 3000 busy, server drifts to 3001+ while client still targets 3000 context7-mcp --http # after — free the port or pin a free one lsof -ti :3000 | xargs kill -9 context7-mcp --http --port 3000
Defensive patterns
Strategy: fallback
Validate before calling
import net from "node:net";
function isFree(port: number, host = "127.0.0.1"): Promise<boolean> {
return new Promise((resolve) => {
const srv = net.createServer();
srv.once("error", () => resolve(false));
srv.once("listening", () => srv.close(() => resolve(true)));
srv.listen(port, host);
});
}
// before start: if (!(await isFree(3000))) port = await findFree(3001); Type guard
function isAddrInUse(err: unknown): err is NodeJS.ErrnoException {
return typeof err === "object" && err !== null && (err as NodeJS.ErrnoException).code === "EADDRINUSE";
} Try / catch
server.once("error", (err) => {
if (isAddrInUse(err) && attemptsLeft) start(port + 1);
else { console.error(`Failed to start server: ${(err as Error).message}`); process.exit(1); }
}); Prevention
- Pass --port explicitly when a client config expects a fixed URL
- Kill stale context7-mcp / dev-server processes before starting
- When auto-retry fires, read the final port from the startup log line and use it in clients
When it happens
Trigger: Starting the server with --http (or a client spawning it) while ports 3000..3009 are occupied — another context7-mcp instance, a dev server that defaults to 3000 (React/Next/Vite), Docker port mappings, or two MCP clients each launching their own copy.
Common situations: Local web dev on port 3000 while an MCP client also starts context7-mcp; a previous server process not terminated after a crash; concurrent CI jobs sharing a host network.
Related errors
- Failed to fetch ${item.path}: ${fileResponse.status}
- downloadData.error || "no files"
- describeConnectionError(error, url)
- await describeErrorResponse(response, fallback)
- errorBody.error || errorBody.message || res.statusText
AI-assisted analysis of upstash/context7@c3248289c2 (2026-08-18).
Data as JSON: /api/errors/9dbf5dcc9424ffc1.
Report an issue: GitHub.