dg-lab-mcp-server 1.0.0 → 1.0.2

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.
package/dist/config.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * @fileoverview 配置管理模块
3
3
  *
4
- * 这个模块负责加载和验证服务器配置。支持通过 .env 文件或环境变量来配置,
4
+ * 这个模块负责加载和验证服务器配置。直接从环境变量读取配置,
5
5
  * 对于未设置的选项会使用合理的默认值。
6
6
  *
7
7
  * 主要功能:
8
- * - 从 .env 文件加载配置
8
+ * - 从环境变量加载配置
9
9
  * - 验证配置值的有效性
10
10
  * - 提供 IP 地址检测(本地和公网)
11
11
  * - 单例模式确保配置一致性
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAqBH;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kCAAkC;IAClC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yCAAyC;IACzC,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAiCD;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,YAAY,CAezC;AAyED;;;;;GAKG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAKxC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAWnC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,CAG5D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kCAAkC;IAClC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yCAAyC;IACzC,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAiCD;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,YAAY,CAezC;AAyED;;;;;GAKG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAKxC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAWnC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,CAG5D"}
package/dist/index.js CHANGED
@@ -1,6 +1,4 @@
1
1
  // src/config.ts
2
- import * as dotenv from "dotenv";
3
- import * as path from "path";
4
2
  import * as os from "os";
5
3
 
6
4
  // src/errors.ts
@@ -66,15 +64,6 @@ var WaveformError = class extends AppError {
66
64
  };
67
65
 
68
66
  // src/config.ts
69
- var envPath = path.resolve(process.cwd(), ".env");
70
- var dotenvResult = dotenv.config({ path: envPath });
71
- if (dotenvResult.error) {
72
- console.log(`[\u914D\u7F6E] .env \u6587\u4EF6\u52A0\u8F7D\u5931\u8D25: ${dotenvResult.error.message}`);
73
- console.log(`[\u914D\u7F6E] \u5C1D\u8BD5\u52A0\u8F7D\u8DEF\u5F84: ${envPath}`);
74
- } else {
75
- console.log(`[\u914D\u7F6E] .env \u6587\u4EF6\u5DF2\u52A0\u8F7D: ${envPath}`);
76
- }
77
- console.log(`[\u914D\u7F6E] PUBLIC_IP \u73AF\u5883\u53D8\u91CF: "${process.env.PUBLIC_IP || "(\u672A\u8BBE\u7F6E)"}"`);
78
67
  function getEnvString(key, defaultValue) {
79
68
  return process.env[key] ?? defaultValue;
80
69
  }
@@ -91,7 +80,7 @@ function getEnvNumber(key, defaultValue) {
91
80
  return parsed;
92
81
  }
93
82
  function loadConfig() {
94
- const config2 = {
83
+ const config = {
95
84
  port: getEnvNumber("PORT", 3323),
96
85
  publicIp: getEnvString("PUBLIC_IP", ""),
97
86
  ssePath: getEnvString("SSE_PATH", "/sse"),
@@ -102,57 +91,57 @@ function loadConfig() {
102
91
  staleDeviceTimeout: getEnvNumber("STALE_DEVICE_TIMEOUT", 36e5),
103
92
  connectionTimeoutMinutes: getEnvNumber("CONNECTION_TIMEOUT_MINUTES", 5)
104
93
  };
105
- validateConfig(config2);
106
- return config2;
94
+ validateConfig(config);
95
+ return config;
107
96
  }
108
- function validateConfig(config2) {
109
- if (config2.port < 1 || config2.port > 65535) {
110
- throw new ConfigError(`\u7AEF\u53E3\u65E0\u6548: ${config2.port}\uFF0C\u5FC5\u987B\u5728 1-65535 \u8303\u56F4\u5185`, {
97
+ function validateConfig(config) {
98
+ if (config.port < 1 || config.port > 65535) {
99
+ throw new ConfigError(`\u7AEF\u53E3\u65E0\u6548: ${config.port}\uFF0C\u5FC5\u987B\u5728 1-65535 \u8303\u56F4\u5185`, {
111
100
  code: "CONFIG_INVALID_PORT" /* CONFIG_INVALID_PORT */,
112
- context: { port: config2.port }
101
+ context: { port: config.port }
113
102
  });
114
103
  }
115
- if (config2.publicIp) {
104
+ if (config.publicIp) {
116
105
  const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
117
- if (!ipv4Regex.test(config2.publicIp)) {
118
- console.warn(`[\u914D\u7F6E] \u26A0\uFE0F \u516C\u7F51IP\u683C\u5F0F\u65E0\u6548: ${config2.publicIp}\uFF0C\u5C06\u4F7F\u7528\u672C\u5730IP`);
119
- config2.publicIp = "";
106
+ if (!ipv4Regex.test(config.publicIp)) {
107
+ console.warn(`[\u914D\u7F6E] \u26A0\uFE0F \u516C\u7F51IP\u683C\u5F0F\u65E0\u6548: ${config.publicIp}\uFF0C\u5C06\u4F7F\u7528\u672C\u5730IP`);
108
+ config.publicIp = "";
120
109
  } else {
121
- const parts = config2.publicIp.split(".");
110
+ const parts = config.publicIp.split(".");
122
111
  if (parts.some((part) => parseInt(part, 10) > 255)) {
123
- console.warn(`[\u914D\u7F6E] \u26A0\uFE0F \u516C\u7F51IP\u683C\u5F0F\u65E0\u6548: ${config2.publicIp}\uFF0C\u6BCF\u6BB5\u5FC5\u987B\u57280-255\u8303\u56F4\u5185\uFF0C\u5C06\u4F7F\u7528\u672C\u5730IP`);
124
- config2.publicIp = "";
112
+ console.warn(`[\u914D\u7F6E] \u26A0\uFE0F \u516C\u7F51IP\u683C\u5F0F\u65E0\u6548: ${config.publicIp}\uFF0C\u6BCF\u6BB5\u5FC5\u987B\u57280-255\u8303\u56F4\u5185\uFF0C\u5C06\u4F7F\u7528\u672C\u5730IP`);
113
+ config.publicIp = "";
125
114
  }
126
115
  }
127
116
  }
128
- if (!config2.ssePath.startsWith("/")) {
129
- throw new ConfigError(`SSE \u8DEF\u5F84\u65E0\u6548: ${config2.ssePath}\uFF0C\u5FC5\u987B\u4EE5 / \u5F00\u5934`, {
117
+ if (!config.ssePath.startsWith("/")) {
118
+ throw new ConfigError(`SSE \u8DEF\u5F84\u65E0\u6548: ${config.ssePath}\uFF0C\u5FC5\u987B\u4EE5 / \u5F00\u5934`, {
130
119
  code: "CONFIG_INVALID_PATH" /* CONFIG_INVALID_PATH */,
131
- context: { path: config2.ssePath, type: "ssePath" }
120
+ context: { path: config.ssePath, type: "ssePath" }
132
121
  });
133
122
  }
134
- if (!config2.postPath.startsWith("/")) {
135
- throw new ConfigError(`POST \u8DEF\u5F84\u65E0\u6548: ${config2.postPath}\uFF0C\u5FC5\u987B\u4EE5 / \u5F00\u5934`, {
123
+ if (!config.postPath.startsWith("/")) {
124
+ throw new ConfigError(`POST \u8DEF\u5F84\u65E0\u6548: ${config.postPath}\uFF0C\u5FC5\u987B\u4EE5 / \u5F00\u5934`, {
136
125
  code: "CONFIG_INVALID_PATH" /* CONFIG_INVALID_PATH */,
137
- context: { path: config2.postPath, type: "postPath" }
126
+ context: { path: config.postPath, type: "postPath" }
138
127
  });
139
128
  }
140
- if (config2.heartbeatInterval < 1e3) {
141
- throw new ConfigError(`\u5FC3\u8DF3\u95F4\u9694\u65E0\u6548: ${config2.heartbeatInterval}\uFF0C\u5FC5\u987B\u81F3\u5C11 1000ms`, {
129
+ if (config.heartbeatInterval < 1e3) {
130
+ throw new ConfigError(`\u5FC3\u8DF3\u95F4\u9694\u65E0\u6548: ${config.heartbeatInterval}\uFF0C\u5FC5\u987B\u81F3\u5C11 1000ms`, {
142
131
  code: "CONFIG_LOAD_FAILED" /* CONFIG_LOAD_FAILED */,
143
- context: { heartbeatInterval: config2.heartbeatInterval }
132
+ context: { heartbeatInterval: config.heartbeatInterval }
144
133
  });
145
134
  }
146
- if (config2.staleDeviceTimeout < 6e4) {
147
- throw new ConfigError(`\u8BBE\u5907\u8FC7\u671F\u8D85\u65F6\u65E0\u6548: ${config2.staleDeviceTimeout}\uFF0C\u5FC5\u987B\u81F3\u5C11 60000ms`, {
135
+ if (config.staleDeviceTimeout < 6e4) {
136
+ throw new ConfigError(`\u8BBE\u5907\u8FC7\u671F\u8D85\u65F6\u65E0\u6548: ${config.staleDeviceTimeout}\uFF0C\u5FC5\u987B\u81F3\u5C11 60000ms`, {
148
137
  code: "CONFIG_LOAD_FAILED" /* CONFIG_LOAD_FAILED */,
149
- context: { staleDeviceTimeout: config2.staleDeviceTimeout }
138
+ context: { staleDeviceTimeout: config.staleDeviceTimeout }
150
139
  });
151
140
  }
152
- if (config2.connectionTimeoutMinutes < 1 || config2.connectionTimeoutMinutes > 60) {
153
- throw new ConfigError(`\u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4\u65E0\u6548: ${config2.connectionTimeoutMinutes}\uFF0C\u5FC5\u987B\u5728 1-60 \u5206\u949F\u8303\u56F4\u5185`, {
141
+ if (config.connectionTimeoutMinutes < 1 || config.connectionTimeoutMinutes > 60) {
142
+ throw new ConfigError(`\u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4\u65E0\u6548: ${config.connectionTimeoutMinutes}\uFF0C\u5FC5\u987B\u5728 1-60 \u5206\u949F\u8303\u56F4\u5185`, {
154
143
  code: "CONFIG_LOAD_FAILED" /* CONFIG_LOAD_FAILED */,
155
- context: { connectionTimeoutMinutes: config2.connectionTimeoutMinutes }
144
+ context: { connectionTimeoutMinutes: config.connectionTimeoutMinutes }
156
145
  });
157
146
  }
158
147
  }
@@ -174,8 +163,8 @@ function getLocalIP() {
174
163
  }
175
164
  return "localhost";
176
165
  }
177
- function getEffectiveIP(config2) {
178
- const cfg = config2 || getConfig();
166
+ function getEffectiveIP(config) {
167
+ const cfg = config || getConfig();
179
168
  return cfg.publicIp || getLocalIP();
180
169
  }
181
170
 
@@ -509,7 +498,7 @@ var JsonRpcHandler = class {
509
498
  };
510
499
 
511
500
  // src/server.ts
512
- function createServer(config2) {
501
+ function createServer(config) {
513
502
  const app = express();
514
503
  app.use((req, res, next) => {
515
504
  res.header("Access-Control-Allow-Origin", "*");
@@ -523,18 +512,18 @@ function createServer(config2) {
523
512
  });
524
513
  app.use(express.json());
525
514
  app.use(express.text({ type: "application/json" }));
526
- const sseTransport = new SSETransport(config2.postPath);
515
+ const sseTransport = new SSETransport(config.postPath);
527
516
  const jsonRpcHandler = new JsonRpcHandler({
528
517
  onError: (error) => {
529
518
  console.error("[JSON-RPC \u9519\u8BEF]", error);
530
519
  }
531
520
  });
532
- app.get(config2.ssePath, (req, res) => {
521
+ app.get(config.ssePath, (req, res) => {
533
522
  console.log("[SSE] \u65B0\u8FDE\u63A5");
534
523
  const connection = sseTransport.connect(req, res);
535
524
  console.log(`[SSE] \u8FDE\u63A5\u5DF2\u5EFA\u7ACB: ${connection.id}`);
536
525
  });
537
- app.post(config2.postPath, async (req, res) => {
526
+ app.post(config.postPath, async (req, res) => {
538
527
  const sessionId = req.query.sessionId;
539
528
  if (!sessionId || !sseTransport.hasConnection(sessionId)) {
540
529
  res.status(400).json({ error: "\u65E0\u6548\u6216\u7F3A\u5C11 sessionId" });
@@ -566,18 +555,18 @@ function createServer(config2) {
566
555
  sseTransport,
567
556
  jsonRpcHandler,
568
557
  async start() {
569
- return new Promise((resolve2) => {
570
- httpServer = app.listen(config2.port, () => {
571
- console.log(`[\u670D\u52A1\u5668] MCP SSE \u670D\u52A1\u5668\u76D1\u542C\u7AEF\u53E3 ${config2.port}`);
572
- console.log(`[\u670D\u52A1\u5668] SSE \u7AEF\u70B9: ${config2.ssePath}`);
573
- console.log(`[\u670D\u52A1\u5668] POST \u7AEF\u70B9: ${config2.postPath}`);
574
- resolve2();
558
+ return new Promise((resolve) => {
559
+ httpServer = app.listen(config.port, () => {
560
+ console.log(`[\u670D\u52A1\u5668] MCP SSE \u670D\u52A1\u5668\u76D1\u542C\u7AEF\u53E3 ${config.port}`);
561
+ console.log(`[\u670D\u52A1\u5668] SSE \u7AEF\u70B9: ${config.ssePath}`);
562
+ console.log(`[\u670D\u52A1\u5668] POST \u7AEF\u70B9: ${config.postPath}`);
563
+ resolve();
575
564
  });
576
565
  this.httpServer = httpServer;
577
566
  });
578
567
  },
579
568
  async stop() {
580
- return new Promise((resolve2) => {
569
+ return new Promise((resolve) => {
581
570
  if (httpServer && httpServer.listening) {
582
571
  httpServer.close((err) => {
583
572
  if (err) {
@@ -585,11 +574,11 @@ function createServer(config2) {
585
574
  } else {
586
575
  console.log("[\u670D\u52A1\u5668] \u5DF2\u505C\u6B62");
587
576
  }
588
- resolve2();
577
+ resolve();
589
578
  });
590
579
  } else {
591
580
  console.log("[\u670D\u52A1\u5668] \u672A\u542F\u52A8\u6216\u5DF2\u5173\u95ED");
592
- resolve2();
581
+ resolve();
593
582
  }
594
583
  });
595
584
  }
@@ -2036,6 +2025,7 @@ function loadWaveforms(storage, filePath = "./data/waveforms.json") {
2036
2025
 
2037
2026
  // src/waveform-parser.ts
2038
2027
  var FREQUENCY_DATASET = [
2028
+ // (10..50) step 1 → 索引 0-40
2039
2029
  10,
2040
2030
  11,
2041
2031
  12,
@@ -2046,29 +2036,42 @@ var FREQUENCY_DATASET = [
2046
2036
  17,
2047
2037
  18,
2048
2038
  19,
2049
- // 0-9
2050
2039
  20,
2040
+ 21,
2051
2041
  22,
2042
+ 23,
2052
2043
  24,
2044
+ 25,
2053
2045
  26,
2046
+ 27,
2054
2047
  28,
2048
+ 29,
2055
2049
  30,
2050
+ 31,
2056
2051
  32,
2052
+ 33,
2057
2053
  34,
2054
+ 35,
2058
2055
  36,
2056
+ 37,
2059
2057
  38,
2060
- // 10-19
2058
+ 39,
2061
2059
  40,
2060
+ 41,
2062
2061
  42,
2062
+ 43,
2063
2063
  44,
2064
+ 45,
2064
2065
  46,
2066
+ 47,
2065
2067
  48,
2068
+ 49,
2066
2069
  50,
2070
+ // (52..80) step 2 → 索引 41-55
2067
2071
  52,
2068
2072
  54,
2069
2073
  56,
2070
2074
  58,
2071
- // 20-29
2072
2075
  60,
2073
2076
  62,
2074
2077
  64,
@@ -2079,56 +2082,40 @@ var FREQUENCY_DATASET = [
2079
2082
  74,
2080
2083
  76,
2081
2084
  78,
2082
- // 30-39
2083
2085
  80,
2086
+ // (85..100) step 5 → 索引 56-59
2084
2087
  85,
2085
2088
  90,
2086
2089
  95,
2087
2090
  100,
2091
+ // (110..200) step 10 → 索引 60-69
2088
2092
  110,
2089
2093
  120,
2090
2094
  130,
2091
2095
  140,
2092
2096
  150,
2093
- // 40-49
2094
2097
  160,
2095
2098
  170,
2096
2099
  180,
2097
2100
  190,
2098
2101
  200,
2099
- 220,
2100
- 240,
2101
- 260,
2102
- 280,
2102
+ // (233..400) step 33 → 索引 70-75
2103
+ 233,
2104
+ 266,
2103
2105
  300,
2104
- // 50-59
2105
- 320,
2106
- 340,
2107
- 360,
2108
- 380,
2106
+ 333,
2107
+ 366,
2109
2108
  400,
2110
- 420,
2111
- 440,
2112
- 460,
2113
- 480,
2109
+ // (450..600) step 50 → 索引 76-79
2110
+ 450,
2114
2111
  500,
2115
- // 60-69
2116
2112
  550,
2117
2113
  600,
2118
- 650,
2114
+ // (700..1000) step 100 → 索引 80-83
2119
2115
  700,
2120
- 750,
2121
2116
  800,
2122
- 850,
2123
2117
  900,
2124
- 950,
2125
- 1e3,
2126
- // 70-79
2127
- 1e3,
2128
- 1e3,
2129
- 1e3,
2130
2118
  1e3
2131
- // 80-83 (上限 1000)
2132
2119
  ];
2133
2120
  var DURATION_DATASET = Array.from({ length: 100 }, (_, i) => i + 1);
2134
2121
  function getFrequencyFromIndex(index) {
@@ -2370,9 +2357,9 @@ function convertToHexWaveforms(sections, _playbackSpeed = 1) {
2370
2357
  // src/tools/waveform-tools.ts
2371
2358
  var waveformStorage = null;
2372
2359
  var storagePath = "./data/waveforms.json";
2373
- function initWaveformStorage(storage, path2) {
2360
+ function initWaveformStorage(storage, path) {
2374
2361
  waveformStorage = storage || new WaveformStorage();
2375
- if (path2) storagePath = path2;
2362
+ if (path) storagePath = path;
2376
2363
  }
2377
2364
  function getWaveformStorage() {
2378
2365
  if (!waveformStorage) {
@@ -3022,17 +3009,17 @@ function registerControlTools(toolManager, sessionManager, wsServer) {
3022
3009
 
3023
3010
  // src/app.ts
3024
3011
  function createApp() {
3025
- const config2 = loadConfig();
3026
- printConfigInfo(config2);
3027
- const server = createServer(config2);
3012
+ const config = loadConfig();
3013
+ printConfigInfo(config);
3014
+ const server = createServer(config);
3028
3015
  const toolManager = new ToolManager(() => {
3029
3016
  broadcastNotification(server, "notifications/tools/list_changed");
3030
3017
  });
3031
- const sessionManager = new SessionManager(config2.connectionTimeoutMinutes);
3032
- console.log(`[\u4F1A\u8BDD] \u4EC5\u5185\u5B58\u6A21\u5F0F\uFF08\u8FDE\u63A5\u8D85\u65F6: ${config2.connectionTimeoutMinutes} \u5206\u949F\uFF0C\u6D3B\u8DC3\u8D85\u65F6: 1 \u5C0F\u65F6\uFF09`);
3033
- const wsServer = createWSServer(config2, sessionManager);
3034
- const waveformStorage2 = initWaveforms(config2);
3035
- registerProtocolAndTools(server, toolManager, sessionManager, wsServer, config2);
3018
+ const sessionManager = new SessionManager(config.connectionTimeoutMinutes);
3019
+ console.log(`[\u4F1A\u8BDD] \u4EC5\u5185\u5B58\u6A21\u5F0F\uFF08\u8FDE\u63A5\u8D85\u65F6: ${config.connectionTimeoutMinutes} \u5206\u949F\uFF0C\u6D3B\u8DC3\u8D85\u65F6: 1 \u5C0F\u65F6\uFF09`);
3020
+ const wsServer = createWSServer(config, sessionManager);
3021
+ const waveformStorage2 = initWaveforms(config);
3022
+ registerProtocolAndTools(server, toolManager, sessionManager, wsServer, config);
3036
3023
  const shutdown = async () => {
3037
3024
  console.log("\n[\u670D\u52A1\u5668] \u6B63\u5728\u5173\u95ED...");
3038
3025
  wsServer.stop();
@@ -3042,7 +3029,7 @@ function createApp() {
3042
3029
  console.log("[\u670D\u52A1\u5668] \u5DF2\u505C\u6B62");
3043
3030
  };
3044
3031
  return {
3045
- config: config2,
3032
+ config,
3046
3033
  server,
3047
3034
  toolManager,
3048
3035
  sessionManager,
@@ -3051,22 +3038,22 @@ function createApp() {
3051
3038
  shutdown
3052
3039
  };
3053
3040
  }
3054
- function printConfigInfo(config2) {
3041
+ function printConfigInfo(config) {
3055
3042
  console.log("=".repeat(50));
3056
3043
  console.log("DG-LAB MCP SSE \u670D\u52A1\u5668");
3057
3044
  console.log("=".repeat(50));
3058
- console.log(`[\u914D\u7F6E] \u7AEF\u53E3: ${config2.port}`);
3059
- console.log(`[\u914D\u7F6E] SSE \u8DEF\u5F84: ${config2.ssePath}`);
3060
- console.log(`[\u914D\u7F6E] POST \u8DEF\u5F84: ${config2.postPath}`);
3061
- const effectiveIP = getEffectiveIP(config2);
3045
+ console.log(`[\u914D\u7F6E] \u7AEF\u53E3: ${config.port}`);
3046
+ console.log(`[\u914D\u7F6E] SSE \u8DEF\u5F84: ${config.ssePath}`);
3047
+ console.log(`[\u914D\u7F6E] POST \u8DEF\u5F84: ${config.postPath}`);
3048
+ const effectiveIP = getEffectiveIP(config);
3062
3049
  const localIP = getLocalIP();
3063
3050
  console.log(`[\u914D\u7F6E] \u672C\u5730 IP: ${localIP}`);
3064
- console.log(`[\u914D\u7F6E] \u516C\u7F51 IP: ${config2.publicIp || "(\u672A\u8BBE\u7F6E)"}`);
3051
+ console.log(`[\u914D\u7F6E] \u516C\u7F51 IP: ${config.publicIp || "(\u672A\u8BBE\u7F6E)"}`);
3065
3052
  console.log(`[\u914D\u7F6E] \u5B9E\u9645\u4F7F\u7528 IP: ${effectiveIP}`);
3066
3053
  }
3067
- function createWSServer(config2, sessionManager) {
3054
+ function createWSServer(config, sessionManager) {
3068
3055
  return new DGLabWSServer({
3069
- heartbeatInterval: config2.heartbeatInterval,
3056
+ heartbeatInterval: config.heartbeatInterval,
3070
3057
  onStrengthUpdate: (controllerId, a, b, limitA, limitB) => {
3071
3058
  console.log(`[WS] ${controllerId} \u5F3A\u5EA6: A=${a}/${limitA}, B=${b}/${limitB}`);
3072
3059
  const session = sessionManager.getSessionByClientId(controllerId);
@@ -3116,20 +3103,20 @@ function createWSServer(config2, sessionManager) {
3116
3103
  }
3117
3104
  });
3118
3105
  }
3119
- function initWaveforms(config2) {
3106
+ function initWaveforms(config) {
3120
3107
  const waveformStorage2 = new WaveformStorage();
3121
- if (loadWaveforms(waveformStorage2, config2.waveformStorePath)) {
3108
+ if (loadWaveforms(waveformStorage2, config.waveformStorePath)) {
3122
3109
  console.log(`[\u6CE2\u5F62] \u4ECE\u78C1\u76D8\u52A0\u8F7D\u4E86 ${waveformStorage2.list().length} \u4E2A\u6CE2\u5F62`);
3123
3110
  }
3124
- initWaveformStorage(waveformStorage2, config2.waveformStorePath);
3111
+ initWaveformStorage(waveformStorage2, config.waveformStorePath);
3125
3112
  return waveformStorage2;
3126
3113
  }
3127
- function registerProtocolAndTools(server, toolManager, sessionManager, wsServer, config2) {
3114
+ function registerProtocolAndTools(server, toolManager, sessionManager, wsServer, config) {
3128
3115
  registerMCPProtocol(server.jsonRpcHandler, () => {
3129
3116
  console.log("[MCP] \u5BA2\u6237\u7AEF\u5DF2\u521D\u59CB\u5316");
3130
3117
  });
3131
3118
  registerToolHandlers(server.jsonRpcHandler, toolManager);
3132
- registerDeviceTools(toolManager, sessionManager, wsServer, config2.publicIp || void 0);
3119
+ registerDeviceTools(toolManager, sessionManager, wsServer, config.publicIp || void 0);
3133
3120
  console.log("[\u5DE5\u5177] \u8BBE\u5907\u5DE5\u5177\u5DF2\u6CE8\u518C");
3134
3121
  registerControlTools(toolManager, sessionManager, wsServer);
3135
3122
  console.log("[\u5DE5\u5177] \u63A7\u5236\u5DE5\u5177\u5DF2\u6CE8\u518C");