1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import express from 'express'; import * as z from 'zod';
// 1. 创建 MCP 服务器(保持不变) const server = new McpServer({ name: 'demo-server', version: '1.0.0' });
// 2. 注册所有工具和资源(保持不变) server.registerTool( 'tell_weird_joke', { title: 'Tell Weird Joke', description: 'Generate a weird joke about a specified topic', inputSchema: z.object({ topic: z.string().describe('The topic of the joke') }) }, async ({ topic }) => { return { content: [{ type: 'text', text: `The weirdest joke about ${topic} is... hahaha!` }], }; } );
server.registerTool( 'add', { title: 'Addition Tool', description: 'Add two numbers', inputSchema: z.object({ a: z.number(), b: z.number() }) }, async ({ a, b }) => { return { content: [{ type: 'text', text: `Result: ${a + b}` }], }; } );
server.registerResource( 'greeting', new ResourceTemplate('greeting://{name}', { list: undefined }), { title: 'Greeting Resource', description: 'Dynamic greeting generator' }, async (uri, { name }) => ({ contents: [{ uri: uri.href, text: `Hello, ${name}!` }] }) );
// 3. 创建 Express 应用 const app = express(); app.use(express.json());
// 4. 添加健康检查端点(可选) app.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); });
// 5. 核心 MCP HTTP 端点 app.post('/mcp', async (req, res) => { // 每个请求创建独立 transport 实例(避免请求 ID 冲突) const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, enableJsonResponse: true // 启用 JSON 响应格式 });
// 请求结束时清理资源 res.on('close', () => { transport.close(); });
try { // 将 transport 连接到 MCP 服务器 await server.connect(transport); // 处理请求并返回响应 await transport.handleRequest(req, res, req.body); } catch (error) { console.error('❌ MCP request error:', error); if (!res.headersSent) { res.status(500).json({ error: 'Internal server error' }); } } });
// 6. 启动 HTTP 服务器 const port = parseInt(process.env.PORT || '3000'); app.listen(port, () => { console.log(`🚀 MCP HTTP Server running at http://localhost:${port}`); console.log(`📡 MCP endpoint: http://localhost:${port}/mcp`); console.log(`🏥 Health check: http://localhost:${port}/health`); }).on('error', error => { console.error('❌ Server error:', error); process.exit(1); });
|