@launchdarkly/mcp-server
Version:
The local [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for [LaunchDarkly](https://launchdarkly.com/) federal and European Union (EU) environments.
151 lines • 5.7 kB
JavaScript
;
/*
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.main = main;
const sse_js_1 = require("@modelcontextprotocol/sdk/server/sse.js");
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
const hostHeaderValidation_js_1 = require("@modelcontextprotocol/sdk/server/middleware/hostHeaderValidation.js");
const express_1 = __importDefault(require("express"));
const console_logger_js_1 = require("../../console-logger.js");
const server_js_1 = require("../../server.js");
const sse_security_js_1 = require("./sse-security.js");
const tls_blocklist_js_1 = require("./tls-blocklist.js");
async function main(flags) {
// INC-289: block the compromised eMudhra intermediates before any request.
(0, tls_blocklist_js_1.installTlsBlocklist)();
const runtimeWarning = (0, tls_blocklist_js_1.unpatchedRuntimeWarning)();
if (runtimeWarning) {
process.stderr.write(runtimeWarning);
}
flags.env?.forEach(([key, value]) => {
process.env[key] = value;
});
switch (flags.transport) {
case "stdio":
await startStdio(flags);
break;
case "sse":
await startSSE(flags);
break;
default:
throw new Error(`Invalid transport: ${flags.transport}`);
}
}
async function startStdio(flags) {
const logger = (0, console_logger_js_1.createConsoleLogger)(flags["log-level"]);
const transport = new stdio_js_1.StdioServerTransport();
const server = (0, server_js_1.createMCPServer)({
logger,
allowedTools: flags.tool,
scopes: flags.scope,
...{ apiKey: flags["api-key"] ?? "" },
serverURL: flags["server-url"],
serverIdx: flags["server-index"],
});
await server.connect(transport);
const abort = async () => {
await server.close();
process.exit(0);
};
process.on("SIGTERM", abort);
process.on("SIGINT", abort);
}
async function startSSE(flags) {
const logger = (0, console_logger_js_1.createConsoleLogger)(flags["log-level"]);
const host = flags.host;
const authToken = flags["auth-token"];
(0, sse_security_js_1.assertSafeSSEBind)(host, authToken);
const app = (0, express_1.default)();
if ((0, sse_security_js_1.isLoopbackHost)(host)) {
app.use((0, hostHeaderValidation_js_1.localhostHostValidation)());
}
if (authToken) {
app.use((0, sse_security_js_1.requireBearerToken)(authToken));
}
const sessions = new Map();
const controller = new AbortController();
app.get("/sse", async (_req, res) => {
const server = (0, server_js_1.createMCPServer)({
logger,
allowedTools: flags.tool,
scopes: flags.scope,
...{ apiKey: flags["api-key"] ?? "" },
serverURL: flags["server-url"],
serverIdx: flags["server-index"],
});
const transport = new sse_js_1.SSEServerTransport("/message", res);
sessions.set(transport.sessionId, { transport, server });
res.on("close", () => {
sessions.delete(transport.sessionId);
void server.close();
});
try {
await server.connect(transport);
}
catch (err) {
logger.error("Failed to open SSE session", {
error: err instanceof Error ? err.message : String(err),
});
sessions.delete(transport.sessionId);
void server.close();
if (!res.headersSent) {
res.status(500).send("Internal Server Error");
}
}
});
app.post("/message", async (req, res) => {
const sessionId = typeof req.query["sessionId"] === "string"
? req.query["sessionId"]
: "";
const session = sessions.get(sessionId);
if (!session) {
res.status(404).send("Unknown session");
return;
}
try {
await session.transport.handlePostMessage(req, res);
}
catch (err) {
logger.error("Failed to handle SSE message", {
error: err instanceof Error ? err.message : String(err),
});
if (!res.headersSent) {
res.status(500).send("Internal Server Error");
}
}
});
const httpServer = app.listen(flags.port, host, () => {
const ha = httpServer.address();
const host = typeof ha === "string" ? ha : `${ha?.address}:${ha?.port}`;
logger.info("MCP HTTP server started", { host });
});
let closing = false;
controller.signal.addEventListener("abort", async () => {
if (closing) {
logger.info("Received second signal. Forcing shutdown.");
process.exit(1);
}
closing = true;
logger.info("Shutting down MCP servers");
await Promise.all([...sessions.values()].map(({ server }) => server.close()));
logger.info("Shutting down HTTP server");
const timer = setTimeout(() => {
logger.info("Forcing shutdown");
process.exit(1);
}, 5000);
httpServer.close(() => {
clearTimeout(timer);
logger.info("Graceful shutdown complete");
process.exit(0);
});
});
const abort = () => controller.abort();
process.on("SIGTERM", abort);
process.on("SIGINT", abort);
}
//# sourceMappingURL=impl.js.map