feat: 添加HTTP服务器支持,更新GitLab API基础URL和默认端口

This commit is contained in:
zhangguoyun committed 2025-12-16 09:53:30 +08:00
1 parent 347096b2e1
commit 81fe4ab2a0
1 file changed
+44 -4
+44 -4
View File
@@ -5,6 +5,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { z } from "zod"; import { z } from "zod";
import http from "http";
// 创建 MCP 服务器实例 // 创建 MCP 服务器实例
// 为其设置一个名字和版本 // 为其设置一个名字和版本
@@ -18,7 +19,7 @@ const server = new McpServer({
* 用于连接到GitLab实例并执行操作 * 用于连接到GitLab实例并执行操作
*/ */
const gitlabApiClient = { const gitlabApiClient = {
baseUrl: process.env.GITLAB_API_BASE_URL || "https://gitlab.com/api/v4", baseUrl: process.env.GITLAB_API_BASE_URL || "https://git.ifengqun.com/api/v4",
token: process.env.GITLAB_ACCESS_TOKEN, token: process.env.GITLAB_ACCESS_TOKEN,
async makeRequest(endpoint, options = {}) { async makeRequest(endpoint, options = {}) {
@@ -484,7 +485,7 @@ function parseArgs() {
const args = process.argv.slice(2); const args = process.argv.slice(2);
const config = { const config = {
transport: 'stdio', // 默认使用 stdio transport: 'stdio', // 默认使用 stdio
port: 3000, // 默认 HTTP 端口 port: 8899, // 默认 HTTP 端口
}; };
for (let i = 0; i < args.length; i++) { for (let i = 0; i < args.length; i++) {
@@ -546,17 +547,56 @@ GitLab MCP 服务器
* 启动 HTTP 服务器(使用 Streamable HTTP 传输) * 启动 HTTP 服务器(使用 Streamable HTTP 传输)
*/ */
async function startHttpServer(port) { async function startHttpServer(port) {
const httpServer = http.createServer(async (req, res) => {
// 处理 CORS
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') {
res.writeHead(204);
res.end();
return;
}
if (req.method === 'GET' && req.url === '/health') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ status: 'healthy', transport: 'http' }));
return;
}
// 所有的 MCP 请求都通过 transport 处理
// StreamableHTTPServerTransport 会处理 GET (SSE) 和 POST (Message)
try {
await transport.handleRequest(req, res);
} catch (error) {
console.error('Error handling request:', error);
if (!res.headersSent) {
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Internal Server Error' }));
}
}
});
const transport = new StreamableHTTPServerTransport({ const transport = new StreamableHTTPServerTransport({
endpoint: '/message', endpoint: '/message',
port: port,
}); });
await server.connect(transport); await server.connect(transport);
return new Promise((resolve, reject) => {
httpServer.listen(port, () => {
console.error(`GitLab MCP 服务器已启动 (Streamable HTTP 模式)`); console.error(`GitLab MCP 服务器已启动 (Streamable HTTP 模式)`);
console.error(`监听端口: ${port}`); console.error(`监听端口: ${port}`);
console.error(`MCP 端点: http://localhost:${port}/message`); console.error(`MCP 端点: http://localhost:${port}/message`);
console.error(`\n使用 POST 请求发送消息到 /message 端点`); resolve(httpServer);
});
httpServer.on('error', (error) => {
console.error('HTTP 服务器启动失败:', error);
reject(error);
});
});
} }
/** /**