UNPKG

current-time-timezone-server

Version:

MCP服务器,提供NTP校准的当前时间和时区相关功能,支持stdio和HTTP/SSE,可配置host和protocol,支持.env文件,返回指定时区的本地时间

113 lines 4.15 kB
import express from "express"; import { randomUUID } from "node:crypto"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js"; import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js"; import dotenv from "dotenv"; import { registerTimeTool } from "./utils/toolRegistration.js"; // Load environment variables dotenv.config(); const app = express(); app.use(express.json()); const transports = {}; const sseTransports = {}; const createMcpServer = () => new McpServer({ name: "current-time-timezone-server", version: "1.1.6" }); const setupServer = (server) => { registerTimeTool(server); }; app.post('/mcp', async (req, res) => { const sessionId = req.headers['mcp-session-id']; let transport; if (sessionId && transports[sessionId]) { transport = transports[sessionId]; } else if (!sessionId && isInitializeRequest(req.body)) { const host = process.env.HOST || 'localhost'; const port = parseInt(process.env.PORT || '3000', 10); const protocol = process.env.PROTOCOL || 'http'; transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (sessionId) => { transports[sessionId] = transport; }, }); transport.onclose = () => { if (transport.sessionId) { delete transports[transport.sessionId]; } }; const server = createMcpServer(); setupServer(server); await server.connect(transport); } else { res.status(400).json({ jsonrpc: '2.0', error: { code: -32000, message: 'Bad Request: No valid session ID provided', }, id: null, }); return; } await transport.handleRequest(req, res, req.body); }); const handleSessionRequest = async (req, res) => { const sessionId = req.headers['mcp-session-id']; if (!sessionId || !transports[sessionId]) { res.status(400).send('Invalid or missing session ID'); return; } const transport = transports[sessionId]; await transport.handleRequest(req, res, req.body); }; // SSE endpoint - for traditional clients app.get('/sse', async (req, res) => { try { const transport = new SSEServerTransport('/messages', res); sseTransports[transport.sessionId] = transport; res.on("close", () => { delete sseTransports[transport.sessionId]; }); const server = createMcpServer(); setupServer(server); await server.connect(transport); } catch (error) { console.error('SSE connection error:', error); res.status(500).send('SSE connection failed'); } }); // Message endpoint - for SSE transport message handling app.post('/messages', async (req, res) => { try { const sessionId = req.query.sessionId; const transport = sseTransports[sessionId]; if (!transport) { res.status(400).send('Corresponding SSE session not found'); return; } await transport.handlePostMessage(req, res, req.body); } catch (error) { console.error('Message processing error:', error); res.status(500).send('Message processing failed'); } }); app.get('/mcp', handleSessionRequest); app.delete('/mcp', handleSessionRequest); const host = process.env.HOST || 'localhost'; const port = parseInt(process.env.PORT || '3000', 10); const protocol = process.env.PROTOCOL || 'http'; app.listen(port, host, () => { console.log(`MCP server running on ${protocol}://${host}:${port}`); console.log(`Streamable HTTP endpoint: ${protocol}://${host}:${port}/mcp`); console.log(`SSE endpoint: ${protocol}://${host}:${port}/sse`); console.log(`SSE message endpoint: ${protocol}://${host}:${port}/messages`); }); //# sourceMappingURL=server.js.map