@douyinfe/semi-mcp 1.0.11 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/http.js +64 -14
  2. package/package.json +1 -1
package/dist/http.js CHANGED
@@ -1329,20 +1329,20 @@ function createMCPServer() {
1329
1329
  function parseArgs() {
1330
1330
  const args = process.argv.slice(2);
1331
1331
  let port = 3000;
1332
- let host = '0.0.0.0';
1332
+ let hosts = [];
1333
1333
  let stateless = false;
1334
1334
  let timeout = 30;
1335
1335
  for(let i = 0; i < args.length; i++)if ('--port' === args[i] && args[i + 1]) {
1336
1336
  port = parseInt(args[i + 1], 10);
1337
1337
  i++;
1338
1338
  } else if ('--host' === args[i] && args[i + 1]) {
1339
- host = args[i + 1];
1339
+ hosts = args[i + 1].split(',').map((h)=>h.trim());
1340
1340
  i++;
1341
1341
  } else if ('-p' === args[i] && args[i + 1]) {
1342
1342
  port = parseInt(args[i + 1], 10);
1343
1343
  i++;
1344
1344
  } else if ('-h' === args[i] && args[i + 1]) {
1345
- host = args[i + 1];
1345
+ hosts = args[i + 1].split(',').map((h)=>h.trim());
1346
1346
  i++;
1347
1347
  } else if ('--stateless' === args[i]) stateless = true;
1348
1348
  else if ('--timeout' === args[i] && args[i + 1]) {
@@ -1359,7 +1359,12 @@ Usage: semi-mcp-http [options]
1359
1359
 
1360
1360
  Options:
1361
1361
  --port, -p PORT 指定监听端口 (默认: 3000)
1362
- --host, -h HOST 指定监听地址 (默认: 0.0.0.0)
1362
+ --host, -h HOSTS 指定监听地址,多个地址用逗号分隔 (默认: ::)
1363
+ :: 表示 IPv6 任意地址(自动支持 IPv4)
1364
+ 0.0.0.0 表示 IPv4 任意地址
1365
+ ::1 表示 IPv6 本地回环
1366
+ 127.0.0.1 表示 IPv4 本地回环
1367
+ 注意: 如果同时指定 0.0.0.0 和 ::,只使用 ::
1363
1368
  --stateless 无状态模式,不生成 session ID
1364
1369
  --timeout, -t MINUTES 会话超时时间,单位分钟 (默认: 30)
1365
1370
  --help 显示帮助信息
@@ -1373,14 +1378,27 @@ Endpoints:
1373
1378
  }
1374
1379
  return {
1375
1380
  port,
1376
- host,
1381
+ hosts,
1377
1382
  stateless,
1378
1383
  timeout
1379
1384
  };
1380
1385
  }
1381
1386
  async function main() {
1382
- const { port, host, stateless, timeout } = parseArgs();
1387
+ const { port, hosts, stateless, timeout } = parseArgs();
1383
1388
  const version = getPackageVersion();
1389
+ let processedHosts = hosts;
1390
+ const hasIPv4All = hosts.includes('0.0.0.0');
1391
+ const hasIPv6All = hosts.includes('::');
1392
+ if (hasIPv4All && hasIPv6All) {
1393
+ processedHosts = hosts.filter((h)=>'0.0.0.0' !== h);
1394
+ console.log(`[${new Date().toISOString()}] 检测到同时监听 IPv4 和 IPv6,使用 :: (IPv6) 统一监听`);
1395
+ }
1396
+ if (0 === processedHosts.length) {
1397
+ processedHosts = [
1398
+ '::'
1399
+ ];
1400
+ console.log(`[${new Date().toISOString()}] 使用默认配置: 监听 IPv6 (::)`);
1401
+ }
1384
1402
  const server = createMCPServer();
1385
1403
  const transport = new StreamableHTTPServerTransport({
1386
1404
  sessionIdGenerator: stateless ? void 0 : ()=>crypto.randomUUID()
@@ -1482,22 +1500,47 @@ async function main() {
1482
1500
  error: '未知的端点'
1483
1501
  }));
1484
1502
  });
1485
- httpServer.listen(port, host, ()=>{
1486
- console.log(`
1503
+ const servers = [];
1504
+ let startedCount = 0;
1505
+ console.log(`
1487
1506
  ╔══════════════════════════════════════════════════════════════╗
1488
1507
  ║ Semi MCP Server (Streamable HTTP) v${version.padEnd(10)} ║
1489
1508
  ╠══════════════════════════════════════════════════════════════╣
1490
- ║ 服务地址: http://${('0.0.0.0' === host ? 'localhost' : host).padEnd(15)}:${String(port).padEnd(5)} ║
1491
1509
  ║ 模式: ${stateless ? '无状态 (Stateless)' : '有状态 (Stateful) '} ║
1492
1510
  ║ 会话超时: ${String(timeout).padEnd(3)} 分钟 ║
1493
-
1494
- ║ 端点: ║
1511
+ ║`);
1512
+ const formatHost = (h)=>{
1513
+ if ('::' === h) return ':: (所有 IPv6)';
1514
+ if ('0.0.0.0' === h) return '0.0.0.0 (所有 IPv4)';
1515
+ if ('::1' === h) return '::1 (IPv6 本地)';
1516
+ if ('127.0.0.1' === h) return '127.0.0.1 (IPv4 本地)';
1517
+ return h;
1518
+ };
1519
+ processedHosts.forEach((host, index)=>{
1520
+ httpServer.on('error', (err)=>{
1521
+ const displayHost = formatHost(host);
1522
+ console.log(`║ ✗ 端点 ${index + 1}: http://${displayHost}:${port}`);
1523
+ console.error(`[${new Date().toISOString()}] 启动失败 [${host}]:`, err.message);
1524
+ });
1525
+ httpServer.listen(port, host, ()=>{
1526
+ startedCount++;
1527
+ const displayHost = formatHost(host);
1528
+ console.log(`║ ✓ 端点 ${index + 1}: http://${displayHost}:${port}`);
1529
+ if (startedCount === processedHosts.length) {
1530
+ console.log(`║ ║
1531
+ ║ 可用端点: ║
1495
1532
  ║ POST /mcp 发送 MCP 请求 ║
1496
1533
  ║ GET /mcp SSE 流 (服务器推送) ║
1497
1534
  ║ GET /health 健康检查 ║
1498
1535
  ╚══════════════════════════════════════════════════════════════╝
1499
1536
  `);
1537
+ console.log(`[${new Date().toISOString()}] 所有服务器已启动,监听 ${processedHosts.length} 个地址`);
1538
+ console.log(`[${new Date().toISOString()}] 总计监听: ${processedHosts.join(', ')}`);
1539
+ }
1540
+ });
1541
+ servers.push(httpServer);
1500
1542
  });
1543
+ processedHosts.length;
1501
1544
  const shutdown = async ()=>{
1502
1545
  console.log('\n正在关闭服务器...');
1503
1546
  try {
@@ -1506,9 +1549,16 @@ async function main() {
1506
1549
  } catch (error) {
1507
1550
  console.error('关闭 transport 时出错:', error);
1508
1551
  }
1509
- httpServer.close(()=>{
1510
- console.log('服务器已关闭');
1511
- process.exit(0);
1552
+ let closedCount = 0;
1553
+ servers.forEach((server, index)=>{
1554
+ server.close(()=>{
1555
+ closedCount++;
1556
+ console.log(`[${new Date().toISOString()}] 服务器 ${index + 1}/${servers.length} 已关闭`);
1557
+ if (closedCount === servers.length) {
1558
+ console.log('所有服务器已关闭');
1559
+ process.exit(0);
1560
+ }
1561
+ });
1512
1562
  });
1513
1563
  };
1514
1564
  process.on('SIGINT', shutdown);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@douyinfe/semi-mcp",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "description": "Semi Design MCP Server - Model Context Protocol server for Semi Design components and documentation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",