UNPKG

@cnbcool/mcp-server

Version:

CNB MCP Server. A comprehensive MCP server that provides seamless integration to the CNB's API(https://cnb.cool), offering a wide range of tools for repository management, pipelines operations and collaboration features

89 lines (88 loc) 3.7 kB
#!/usr/bin/env node "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _a; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const sse_js_1 = require("@modelcontextprotocol/sdk/server/sse.js"); const dotenv_1 = __importDefault(require("dotenv")); const createMcpServer_js_1 = require("./helpers/createMcpServer.js"); const sendResponse_js_1 = require("./helpers/sendResponse.js"); const createTransport_js_1 = require("./helpers/createTransport.js"); dotenv_1.default.config(); const DEFAULT_APP_PORT = 3000; const app = (0, express_1.default)(); app.use(express_1.default.json()); app.post('/mcp', async (req, res) => { let transport; try { transport = process.env.MODE_STATELESS ? await (0, createTransport_js_1.createStatelessStreamableTransport)(req, res) : await (0, createTransport_js_1.createStreamableTransport)(req); } catch (err) { if (typeof err === 'object' && err !== null && 'status' in err && 'message' in err) { const { status, message } = err; (0, sendResponse_js_1.stopWithError)(res, status, message); return; } const message = err instanceof Error ? err.message : String(err); (0, sendResponse_js_1.stopWithServerError)(res, message !== null && message !== void 0 ? message : 'Unknown error'); return; } await transport.handleRequest(req, res, req.body); }); const handleSessionRequest = async (req, res) => { if (process.env.MODE_STATELESS) { (0, sendResponse_js_1.stopWithMethodNotAllowed)(res, 'Method not allowed'); return; } const sessionId = req.headers['mcp-session-id']; if (!sessionId || !createTransport_js_1.transports.streamable[sessionId]) { res.status(400).send('Invalid or missing session ID'); return; } const transport = createTransport_js_1.transports.streamable[sessionId]; await transport.handleRequest(req, res, req.body); }; // SSE notifications not supported in stateless mode app.get('/mcp', handleSessionRequest); // Session termination not needed in stateless mode app.delete('/mcp', handleSessionRequest); app.get('/sse', async (req, res) => { const transport = new sse_js_1.SSEServerTransport('/messages', res); createTransport_js_1.transports.sse[transport.sessionId] = transport; res.on('close', () => { delete createTransport_js_1.transports.sse[transport.sessionId]; }); const mcpServer = (0, createMcpServer_js_1.createMcpServer)(req); await mcpServer.connect(transport); }); app.post('/messages', async (req, res) => { const sessionId = req.query.sessionId; const transport = createTransport_js_1.transports.sse[sessionId]; if (!transport) { res.status(400).send('No transport found for sessionId'); return; } if (!(transport instanceof sse_js_1.SSEServerTransport)) { (0, sendResponse_js_1.stopWithBadRequest)(res, 'Bad Request: Session exists but uses a different transport protocol'); return; } await transport.handlePostMessage(req, res, req.body); }); let port = parseInt((_a = process.env.APP_PORT) !== null && _a !== void 0 ? _a : '', 10); if (isNaN(port)) { port = DEFAULT_APP_PORT; } const server = app.listen(port, () => { console.log(`MCP Streamable HTTP Server listening on port ${port}`); }); process.on('SIGTERM', () => { console.log('SIGTERM signal received: closing HTTP server'); server.close(() => { console.log('HTTP server closed'); }); });