feat(mcps): migrate gitea and memory MCPs to SSE transport on pm2

This commit is contained in:
2026-03-04 10:05:08 +01:00
parent ddf896e3f9
commit ee3d7714c2
8 changed files with 123 additions and 20 deletions

View File

@@ -6,15 +6,18 @@
"type": "module",
"scripts": {
"build": "tsc",
"start": "node --env-file-if-exists=../../.env dist/index.js"
"start": "node dist/start.js"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.5.0",
"zod": "^3.23.8",
"axios": "^1.7.2"
"axios": "^1.7.2",
"dotenv": "^17.3.1",
"express": "^5.2.1",
"zod": "^3.23.8"
},
"devDependencies": {
"typescript": "^5.5.3",
"@types/node": "^20.14.10"
"@types/express": "^5.0.6",
"@types/node": "^20.14.10",
"typescript": "^5.5.3"
}
}
}

View File

@@ -1,5 +1,6 @@
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import express from 'express';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
@@ -251,9 +252,27 @@ async function pollSubscriptions() {
async function run() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Gitea MCP Native Server running on stdio");
const app = express();
let transport: SSEServerTransport | null = null;
app.get('/sse', async (req, res) => {
console.error('New SSE connection established');
transport = new SSEServerTransport('/message', res);
await server.connect(transport);
});
app.post('/message', async (req, res) => {
if (!transport) {
res.status(400).send('No active SSE connection');
return;
}
await transport.handlePostMessage(req, res);
});
const PORT = process.env.GITEA_MCP_PORT || 3001;
app.listen(PORT, () => {
console.error(`Gitea MCP Native Server running on http://localhost:${PORT}/sse`);
});
// Start the background poller
pollSubscriptions();

View File

@@ -0,0 +1,16 @@
import { config } from 'dotenv';
import { resolve } from 'path';
import { fileURLToPath } from 'url';
const __dirname = fileURLToPath(new URL('.', import.meta.url));
// Try to load .env.local first (contains credentials usually)
config({ path: resolve(__dirname, '../../../.env.local') });
// Fallback to .env (contains defaults)
config({ path: resolve(__dirname, '../../../.env') });
// Now boot the compiled MCP index
import('./index.js').catch(err => {
console.error('Failed to start MCP Server:', err);
process.exit(1);
});

View File

@@ -6,7 +6,7 @@
"type": "module",
"scripts": {
"build": "tsc",
"start": "node --env-file-if-exists=../../.env dist/index.js",
"start": "node dist/start.js",
"dev": "tsx watch src/index.ts",
"test:unit": "vitest run"
},
@@ -14,12 +14,15 @@
"@modelcontextprotocol/sdk": "^1.5.0",
"@qdrant/js-client-rest": "^1.12.0",
"@xenova/transformers": "^2.17.2",
"dotenv": "^17.3.1",
"express": "^5.2.1",
"zod": "^3.23.8"
},
"devDependencies": {
"typescript": "^5.5.3",
"@types/express": "^5.0.6",
"@types/node": "^20.14.10",
"tsx": "^4.19.1",
"typescript": "^5.5.3",
"vitest": "^2.1.3"
}
}
}

View File

@@ -1,5 +1,6 @@
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import express from 'express';
import { z } from 'zod';
import { QdrantMemoryService } from './qdrant.js';
@@ -67,9 +68,27 @@ async function main() {
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('Memory MCP server is running and ready to accept connections over stdio.');
const app = express();
let transport: SSEServerTransport | null = null;
app.get('/sse', async (req, res) => {
console.error('New SSE connection established');
transport = new SSEServerTransport('/message', res);
await server.connect(transport);
});
app.post('/message', async (req, res) => {
if (!transport) {
res.status(400).send('No active SSE connection');
return;
}
await transport.handlePostMessage(req, res);
});
const PORT = process.env.MEMORY_MCP_PORT || 3002;
app.listen(PORT, () => {
console.error(`Memory MCP server is running on http://localhost:${PORT}/sse`);
});
}
main().catch((error) => {

View File

@@ -0,0 +1,16 @@
import { config } from 'dotenv';
import { resolve } from 'path';
import { fileURLToPath } from 'url';
const __dirname = fileURLToPath(new URL('.', import.meta.url));
// Try to load .env.local first (contains credentials usually)
config({ path: resolve(__dirname, '../../../.env.local') });
// Fallback to .env (contains defaults)
config({ path: resolve(__dirname, '../../../.env') });
// Now boot the compiled MCP index
import('./index.js').catch(err => {
console.error('Failed to start MCP Server:', err);
process.exit(1);
});