freeform-modeling-mcp 1.0.29 → 1.0.30

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.
@@ -0,0 +1,26 @@
1
+ {
2
+ "mcpServers": {
3
+ "freeform-modeling-mcp": {
4
+ "command": "npx",
5
+ "args": [
6
+ "tsx",
7
+ "src/cli.ts",
8
+ "start",
9
+ "--stdio"
10
+ ],
11
+ "cwd": "D:\\wain\\mcp-server"
12
+ },
13
+ "aholo-sdk-mcp": {
14
+ "type": "stdio",
15
+ "command": "npx",
16
+ "args": [
17
+ "-y",
18
+ "@manycore/aholo-sdk-mcp"
19
+ ],
20
+ "env": {
21
+ "AHOLO_API_KEY": "urSuPSeAcEnNEEn",
22
+ "AHOLO_REGION": "cn"
23
+ }
24
+ }
25
+ }
26
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "freeform-modeling-mcp",
3
- "version": "1.0.29",
3
+ "version": "1.0.30",
4
4
  "description": "KooMaster MCP Server with WebSocket Bridge",
5
5
  "main": "index.cjs",
6
6
  "type": "module",
@@ -18,7 +18,7 @@ export async function startMCPServer(options: { dev?: boolean, stdio?: boolean }
18
18
  const wsBridge = new WebSocketBridge();
19
19
  await wsBridge.initialize();
20
20
  const wsPort = wsBridge.getPort();
21
- const wsUrl = `ws://localhost:${wsPort}`;
21
+ const wsUrl = `ws://127.0.0.1:${wsPort}`;
22
22
 
23
23
  await llmClient.connect(wsUrl);
24
24
 
@@ -6,6 +6,25 @@ import * as http from 'http';
6
6
  import { BridgeLockManager, getActiveBridges } from './lock';
7
7
  import logger from '../logger';
8
8
 
9
+ function isAllowedOrigin(origin: string): boolean {
10
+ try {
11
+ const { hostname } = new URL(origin);
12
+ return hostname === 'localhost' || hostname === '127.0.0.1'
13
+ || hostname === 'kujiale.com' || hostname.endsWith('.kujiale.com')
14
+ || hostname === 'coohom.com' || hostname.endsWith('.coohom.com');
15
+ } catch {
16
+ return false;
17
+ }
18
+ }
19
+
20
+ function setCors(req: http.IncomingMessage, res: http.ServerResponse): void {
21
+ const origin = req.headers.origin;
22
+ if (origin && isAllowedOrigin(origin)) {
23
+ res.setHeader('Access-Control-Allow-Origin', origin);
24
+ res.setHeader('Vary', 'Origin');
25
+ }
26
+ }
27
+
9
28
  // 客户端类型
10
29
  export enum ClientType {
11
30
  MCP = 'mcp',
@@ -101,14 +120,21 @@ export class WebSocketBridge extends EventEmitter {
101
120
  // 使用锁管理器获取可用端口
102
121
  this.port = await this.lockManager.initialize();
103
122
 
104
- // 创建 HTTP 服务器
123
+ // 创建 HTTP 服务器(与 WebSocket 共用端口;/bridge-status 供浏览器发现)
105
124
  this.httpServer = http.createServer((req, res) => {
106
- // 处理HTTP请求
125
+ if (req.method === 'OPTIONS') {
126
+ setCors(req, res);
127
+ res.writeHead(204);
128
+ res.end();
129
+ return;
130
+ }
107
131
  if (req.url === '/bridge-status') {
132
+ setCors(req, res);
108
133
  res.writeHead(200, { 'Content-Type': 'application/json' });
109
134
  res.end(JSON.stringify({
110
135
  service: 'WebSocketBridge',
111
136
  version: '1.0.0',
137
+ port: this.port,
112
138
  status: this._status,
113
139
  clients: {
114
140
  total: this.clients.size,
@@ -122,8 +148,10 @@ export class WebSocketBridge extends EventEmitter {
122
148
  }
123
149
  });
124
150
 
125
- // 创建 WebSocket 服务器
126
- this.server = new WebSocketServer({ server: this.httpServer });
151
+ this.server = new WebSocketServer({
152
+ server: this.httpServer,
153
+ verifyClient: ({ origin }) => !origin || isAllowedOrigin(origin),
154
+ });
127
155
 
128
156
  // 设置事件处理程序
129
157
  this.setupEventHandlers();
@@ -184,8 +212,7 @@ export class WebSocketBridge extends EventEmitter {
184
212
  }
185
213
  });
186
214
 
187
- // 启动 HTTP 服务器
188
- this.httpServer!.listen(this.port);
215
+ this.httpServer!.listen(this.port, '127.0.0.1');
189
216
  } catch (error) {
190
217
  logger.error('Failed to start WebSocketBridge:', error);
191
218
  reject(error);
@@ -75,7 +75,7 @@ function isProcessRunning(pid: number): boolean {
75
75
  // 检查特定端口是否有WebSocketBridge服务响应
76
76
  async function checkBridgeAtPort(port: number): Promise<boolean> {
77
77
  return new Promise((resolve) => {
78
- const req = http.get(`http://localhost:${port}/bridge-status`, (res) => {
78
+ const req = http.get(`http://127.0.0.1:${port}/bridge-status`, (res) => {
79
79
  // 收到响应,检查是否是我们的服务
80
80
  let data = '';
81
81
  res.on('data', (chunk) => {
@@ -186,7 +186,7 @@ export class BridgeLockManager extends EventEmitter {
186
186
  if (!portAvailable) {
187
187
  logger.info(`Port ${this.port} is not available, searching for another port...`);
188
188
  try {
189
- this.port = await findAvailablePort(this.port + 1);
189
+ this.port = await findAvailablePort(this.port + 1, 10);
190
190
  logger.info(`Found available port: ${this.port}`);
191
191
  } catch (e) {
192
192
  logger.error(`Cannot find available port:`, e.message);