mcp-hub-003: Client SSE transport and message relay

This commit is contained in:
Agent 2026-03-12 17:13:36 +00:00
parent a93bcfffa7
commit 9a61026bca
4 changed files with 114 additions and 2 deletions

51
src/routes/mcp-proxy.js Normal file
View file

@ -0,0 +1,51 @@
const { Router } = require('express');
const { v4: uuidv4 } = require('uuid');
const registry = require('../backend-registry');
const relay = require('../relay');
const router = Router();
const sessions = new Map();
router.get('/:serviceId/sse', (req, res) => {
const { serviceId } = req.params;
if (!registry.get(serviceId)) {
return res.status(502).json({ error: 'backend not connected' });
}
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.flushHeaders();
const clientSessionId = uuidv4();
sessions.set(clientSessionId, { res, serviceId });
res.write('event: endpoint\ndata: /' + serviceId + '/message?sessionId=' + clientSessionId + '\n\n');
req.on('close', () => {
sessions.delete(clientSessionId);
console.log('[sse] client disconnected: ' + clientSessionId + ' (' + serviceId + ')');
});
});
router.post('/:serviceId/message', (req, res) => {
const { serviceId } = req.params;
const { sessionId } = req.query;
const session = sessions.get(sessionId);
if (!session) {
return res.status(404).json({ error: 'session not found' });
}
if (!registry.get(serviceId)) {
return res.status(502).json({ error: 'backend not connected' });
}
relay.sendToBackend(serviceId, req.body, sessionId);
return res.status(202).json({ status: 'accepted' });
});
module.exports = router;
module.exports.sessions = sessions;