Skip to main content
Glama
wqhui
by wqhui
http.ts3.9 kB
import express, { Request, Response } from 'express'; import cors from 'cors'; import { randomUUID } from 'crypto'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import { Server as HttpServer } from 'http'; import { logger } from '../utils/logger'; export interface HttpServerConfig { port: number; host?: string; corsOrigins?: string[]; } export interface HttpServerInstance { app: express.Application; server: HttpServer | null; stop: () => Promise<void>; } function setupMiddleware(app: express.Application) { // 简化的 CORS 配置,允许所有本地请求 app.use(cors({ origin: true, // 允许所有源(开发环境) credentials: true, methods: ['GET', 'POST', 'OPTIONS', 'DELETE'], allowedHeaders: ['Content-Type', 'Accept', 'Origin', 'Mcp-Session-Id', 'Authorization'] })); app.use(express.json({ limit: '10mb' })); app.use(express.text()); app.use(express.urlencoded({ extended: true })); app.use((req, res, next) => { logger.info('Received request', req.method, req.url); next(); }); } export async function startHttpServer(mcpServer: McpServer, config: HttpServerConfig): Promise<HttpServerInstance> { const app = express(); setupMiddleware(app); let httpServer: HttpServer | null = null; // 创建 HTTP Streamable Transport const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), }); // MCP Server 连接 Transport await mcpServer.connect(transport); // MCP 端点 app.all('/mcp', async (req: Request, res: Response) => { try { await transport.handleRequest(req, res, req.body); } catch (error) { logger.error('Error handling MCP request:', error); if (!res.headersSent) { res.status(500).json({ jsonrpc: '2.0', error: { code: -32603, message: 'Internal server error', }, id: null, }); } } }); // 健康检查端点 app.get('/health', (req: Request, res: Response) => { res.json({ status: 'healthy', timestamp: new Date().toISOString(), mode: 'http', tools: ['trigger_pipeline', 'get_pipeline_status', 'list_pipelines', 'get_pipeline_jobs', 'cancel_pipeline'] }); }); // 启动 HTTP 服务器 const host = config.host || '127.0.0.1'; return new Promise((resolve, reject) => { httpServer = app.listen(config.port, host, () => { console.error('='.repeat(50)); console.error('🚀 GitLab MCP 服务器已启动'); console.error('📋 模式: Streamable HTTP'); console.error(`🌐 服务地址: http://localhost:${config.port}`); console.error(`🌐 服务地址: http://127.0.0.1:${config.port}`); if (host !== '127.0.0.1' && host !== 'localhost') { console.error(`🌐 服务地址: http://${host}:${config.port}`); } console.error(`🔗 MCP 端点: http://localhost:${config.port}/mcp`); console.error(`💚 健康检查: http://localhost:${config.port}/health`); console.error('🛠️ 可用工具: trigger_pipeline, get_pipeline_status, list_pipelines, get_pipeline_jobs, cancel_pipeline'); console.error('='.repeat(50)); const instance: HttpServerInstance = { app, server: httpServer, stop: async () => { return new Promise((resolve) => { if (httpServer) { httpServer.close(() => { console.error('🛑 GitLab MCP 服务器已停止'); resolve(); }); } else { resolve(); } }); } }; resolve(instance); }); httpServer.on('error', (error: Error) => { reject(error); }); }); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wqhui/mcp-gitlab'

If you have feedback or need assistance with the MCP directory API, please join our Discord server