UNPKG

@sei-js/mcp-server

Version:

Model Context Protocol (MCP) server for interacting with EVM-compatible networks

78 lines (77 loc) 2.98 kB
import express from 'express'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import { getServer } from '../server.js'; export class StreamableHttpTransport { constructor(port = 8080, host = 'localhost', path = '/mcp') { this.mode = 'streamable-http'; this.port = port; this.host = host; this.path = path; } // Note: server parameter ignored for now as this is a stateless server // TODO: allow creating both stateless and stateful remote MCP servers async start(_server) { this.app = express(); this.app.use(express.json()); this.app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'POST, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type'); if (req.method === 'OPTIONS') { return res.sendStatus(200); } next(); }); this.app.post(this.path, async (req, res) => { try { // Create fresh MCP server for this request (stateless design) const mcpServer = await getServer(); const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined // For stateless servers }); res.on('close', () => { console.log('Request closed'); transport.close(); mcpServer.close(); }); await mcpServer.connect(transport); await transport.handleRequest(req, res, req.body); } catch (error) { console.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 }); } } }); this.server = this.app.listen(this.port, this.host, () => { console.error(`MCP Server ready (streamable-http transport on ${this.host}:${this.port}${this.path})`); }); this.server.on('error', (error) => { console.error('Error starting server:', error); }); } async stop() { if (this.server) { return new Promise((resolve) => { if (this.server) { this.server.close(() => { this.server = undefined; this.app = undefined; resolve(); }); } else { resolve(); } }); } } }