@atlisp/mcp 1.0.22 → 1.0.23
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/package.json +1 -1
- package/src/atlisp-mcp.js +25 -11
- package/src/cad-worker.js +11 -11
- package/src/constants.js +1 -1
- package/src/handlers/cad-handlers.js +0 -19
- package/src/handlers/resource-handlers.js +21 -8
- package/src/sse-session.js +3 -3
package/package.json
CHANGED
package/src/atlisp-mcp.js
CHANGED
|
@@ -75,11 +75,16 @@ const TOOL_HANDLERS = {
|
|
|
75
75
|
search_packages: (a) => packageHandlers.searchPackages(a.query),
|
|
76
76
|
install_package: (a) => packageHandlers.installPackage(a.packageName),
|
|
77
77
|
get_platform_info: () => ({ content: [{ type: 'text', text: `支持的 CAD 平台:\n${CAD_PLATFORMS.join('\n')}\n当前连接: ${cad.connected ? '已连接' : '未连接'}` }] }),
|
|
78
|
+
get_file_extensions: (a) => {
|
|
79
|
+
const exts = FILE_EXTENSIONS[a.platform];
|
|
80
|
+
if (!exts) return { content: [{ type: 'text', text: `错误: 不支持的平台 "${a.platform}"` }], isError: true };
|
|
81
|
+
return { content: [{ type: 'text', text: `${a.platform} 文件扩展名: ${exts.join(', ')}` }] };
|
|
82
|
+
},
|
|
83
|
+
get_install_code: () => ({ content: [{ type: 'text', text: `复制以下代码到 CAD 命令行安装 @lisp:\n\n(progn(vl-load-com)(setq s strcat h "http" o(vlax-create-object (s"win"h".win"h"request.5.1"))v vlax-invoke e eval r read)(v o'open "get" (s h"://atlisp.""cn/@"):vlax-true)(v o'send)(v o'WaitforResponse 1000)(e(r(vlax-get-property o'ResponseText))))` }] }),
|
|
78
84
|
at_command: (a) => cadHandlers.atCommand(a.command),
|
|
79
85
|
new_document: () => cadHandlers.newDocument(),
|
|
80
86
|
bring_to_front: () => cadHandlers.bringToFront(),
|
|
81
87
|
install_atlisp: () => cadHandlers.installAtlisp(),
|
|
82
|
-
init_atlisp: () => cadHandlers.initAtlisp(),
|
|
83
88
|
get_function_usage: (a) => functionHandlers.getFunctionUsage(a.name, a.package),
|
|
84
89
|
list_functions: (a) => functionHandlers.listFunctions(a.package),
|
|
85
90
|
};
|
|
@@ -144,6 +149,20 @@ export const tools = [
|
|
|
144
149
|
description: '获取 CAD 平台信息',
|
|
145
150
|
inputSchema: { type: 'object', properties: {} }
|
|
146
151
|
},
|
|
152
|
+
{
|
|
153
|
+
name: 'get_file_extensions',
|
|
154
|
+
description: '获取指定平台的文件扩展名',
|
|
155
|
+
inputSchema: {
|
|
156
|
+
type: 'object',
|
|
157
|
+
properties: { platform: { type: 'string', enum: CAD_PLATFORMS, description: 'CAD 平台' } },
|
|
158
|
+
required: ['platform']
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: 'get_install_code',
|
|
163
|
+
description: '获取 @lisp 安装代码',
|
|
164
|
+
inputSchema: { type: 'object', properties: {} }
|
|
165
|
+
},
|
|
147
166
|
{
|
|
148
167
|
name: 'at_command',
|
|
149
168
|
description: '执行 @lisp 命令',
|
|
@@ -168,11 +187,6 @@ export const tools = [
|
|
|
168
187
|
description: '在 CAD 中安装 @lisp',
|
|
169
188
|
inputSchema: { type: 'object', properties: {} }
|
|
170
189
|
},
|
|
171
|
-
{
|
|
172
|
-
name: 'init_atlisp',
|
|
173
|
-
description: '初始化 CAD 中的 @lisp 环境,加载函数库和初始变量',
|
|
174
|
-
inputSchema: { type: 'object', properties: {} }
|
|
175
|
-
},
|
|
176
190
|
{
|
|
177
191
|
name: 'get_function_usage',
|
|
178
192
|
description: '获取 @lisp 函数用法(从本地 JSON 库)',
|
|
@@ -233,7 +247,7 @@ async function initCadConnection() {
|
|
|
233
247
|
const connected = await cad.connect();
|
|
234
248
|
if (connected) {
|
|
235
249
|
log('Auto-connected to CAD: ' + cad.getPlatform() + ' ' + cad.getVersion());
|
|
236
|
-
console.
|
|
250
|
+
console.log('已自动连接到 CAD: ' + cad.getPlatform() + ' ' + cad.getVersion());
|
|
237
251
|
} else {
|
|
238
252
|
log('No CAD found on startup');
|
|
239
253
|
}
|
|
@@ -368,12 +382,12 @@ async function handleMcpRequest(session, method, params, id) {
|
|
|
368
382
|
}
|
|
369
383
|
|
|
370
384
|
export async function startServer() {
|
|
371
|
-
if (transport === 'stdio') {
|
|
385
|
+
if (config.transport === 'stdio') {
|
|
372
386
|
await initCadConnection();
|
|
373
387
|
const mcpServer = createMcpServer();
|
|
374
|
-
const
|
|
375
|
-
await mcpServer.connect(
|
|
376
|
-
console.
|
|
388
|
+
const stdioTransport = new StdioServerTransport();
|
|
389
|
+
await mcpServer.connect(stdioTransport);
|
|
390
|
+
console.log(`${SERVER_NAME} 运行在 stdio 模式`);
|
|
377
391
|
} else {
|
|
378
392
|
const app = express();
|
|
379
393
|
|
package/src/cad-worker.js
CHANGED
|
@@ -137,7 +137,7 @@ const cadSendWithResult = edge.func(function() {/*
|
|
|
137
137
|
|
|
138
138
|
// 生成 LISP 代码:执行 code,将结果打印到 tempFile
|
|
139
139
|
// 使用 princ 输出原始字符串
|
|
140
|
-
string lispCode = "(progn(setq f(open \"" + tempFile.Replace("\\", "\\\\") + "\" \"w\"))(princ " + code + " f)(close f)(princ))";
|
|
140
|
+
string lispCode = "(progn(setq f(open \"" + tempFile.Replace("\\", "\\\\") + "\" \"w\"))(princ (progn " + code + ") f)(close f)(princ))";
|
|
141
141
|
|
|
142
142
|
// 使用系统 ANSI 编码以兼容 GstarCAD / ZWCAD
|
|
143
143
|
System.IO.File.WriteAllText(lispFile, lispCode, System.Text.Encoding.GetEncoding(System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage));
|
|
@@ -337,22 +337,22 @@ async function waitForIdle(platform) {
|
|
|
337
337
|
function checkParens(code) {
|
|
338
338
|
let depth = 0;
|
|
339
339
|
let inString = false;
|
|
340
|
-
let escapeNext = false;
|
|
341
340
|
for (let i = 0; i < code.length; i++) {
|
|
342
341
|
const ch = code[i];
|
|
343
|
-
if (
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
342
|
+
if (inString) {
|
|
343
|
+
if (ch === '\\' && i + 1 < code.length) {
|
|
344
|
+
i++;
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (ch === '"') {
|
|
348
|
+
inString = false;
|
|
349
|
+
}
|
|
349
350
|
continue;
|
|
350
351
|
}
|
|
351
352
|
if (ch === '"') {
|
|
352
|
-
inString =
|
|
353
|
+
inString = true;
|
|
353
354
|
continue;
|
|
354
355
|
}
|
|
355
|
-
if (inString) continue;
|
|
356
356
|
if (ch === ';') {
|
|
357
357
|
while (i < code.length && code[i] !== '\n') i++;
|
|
358
358
|
continue;
|
|
@@ -427,7 +427,7 @@ async function handleMessage(msg) {
|
|
|
427
427
|
if (!parenCheck.valid) {
|
|
428
428
|
return { success: false, error: `括号错误: ${parenCheck.error} (位置 ${parenCheck.pos})` };
|
|
429
429
|
}
|
|
430
|
-
if (!(await waitForIdle(msg.platform))) {
|
|
430
|
+
if (!(await waitForIdle(msg.platform || 'AutoCAD'))) {
|
|
431
431
|
return { success: false, error: 'CAD is busy, timeout' };
|
|
432
432
|
}
|
|
433
433
|
log(`send: ${msg.code}`);
|
package/src/constants.js
CHANGED
|
@@ -8,7 +8,7 @@ export const FILE_EXTENSIONS = {
|
|
|
8
8
|
|
|
9
9
|
export const PROTOCOL_VERSION = '2024-11-05';
|
|
10
10
|
export const SERVER_NAME = 'atlisp-mcp-server';
|
|
11
|
-
export const SERVER_VERSION = '1.0.
|
|
11
|
+
export const SERVER_VERSION = '1.0.24';
|
|
12
12
|
|
|
13
13
|
export const MOCK_PACKAGES = [
|
|
14
14
|
{ name: 'base', description: '基础函数库', version: '1.0.0' },
|
|
@@ -77,22 +77,3 @@ export async function installAtlisp() {
|
|
|
77
77
|
await cad.sendCommand(installCode + '\n');
|
|
78
78
|
return { content: [{ type: 'text', text: '已发送 @lisp 安装代码到 CAD' }] };
|
|
79
79
|
}
|
|
80
|
-
|
|
81
|
-
export async function initAtlisp() {
|
|
82
|
-
if (!cad.connected) { await cad.connect(); }
|
|
83
|
-
if (!cad.connected) return { content: [{ type: 'text', text: '未连接 CAD' }], isError: true };
|
|
84
|
-
const code = `(if (null @::load-module)
|
|
85
|
-
(progn
|
|
86
|
-
(vl-load-com)
|
|
87
|
-
(setq s strcat h"http"o(vlax-create-object (s"win"h".win"h"request.5.1"))
|
|
88
|
-
v vlax-invoke e eval r read)(v o'open "get" (s h"://""atlisp.""cn/cloud"):vlax-true)
|
|
89
|
-
(v o'send)
|
|
90
|
-
(v o'WaitforResponse 1000)
|
|
91
|
-
(e(r(vlax-get o'ResponseText)))))`;
|
|
92
|
-
try {
|
|
93
|
-
await cad.sendCommand(code + '\n');
|
|
94
|
-
return { content: [{ type: 'text', text: '已发送 @lisp 函数库加载代码到 CAD' }] };
|
|
95
|
-
} catch (e) {
|
|
96
|
-
return { content: [{ type: 'text', text: `错误: ${e.message}` }], isError: true };
|
|
97
|
-
}
|
|
98
|
-
}
|
|
@@ -312,16 +312,29 @@ async function getDwgPath() {
|
|
|
312
312
|
if (!cad.connected) return { path: null, name: null };
|
|
313
313
|
|
|
314
314
|
try {
|
|
315
|
-
const code = `(
|
|
316
|
-
|
|
315
|
+
const code = `(progn
|
|
316
|
+
(setq prefix (vl-princ-to-string (getvar "dwgprefix")))
|
|
317
|
+
(setq name (vl-princ-to-string (getvar "dwgname")))
|
|
318
|
+
(list (strcat prefix name) name)
|
|
319
|
+
)`;
|
|
320
|
+
const result = await cad.sendCommandWithResult(code);
|
|
317
321
|
|
|
318
|
-
|
|
319
|
-
|
|
322
|
+
if (!result || result === "nil" || result === "") {
|
|
323
|
+
return { path: null, name: null };
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
let parsed = null;
|
|
327
|
+
try { parsed = JSON.parse(result); } catch {}
|
|
328
|
+
if (!parsed) {
|
|
329
|
+
const listResult = parseLispList(result);
|
|
330
|
+
if (listResult && listResult.length >= 2) parsed = listResult;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (parsed && Array.isArray(parsed) && parsed.length >= 2) {
|
|
334
|
+
return { path: String(parsed[0]), name: String(parsed[1]) };
|
|
335
|
+
}
|
|
320
336
|
|
|
321
|
-
return {
|
|
322
|
-
path: fullPath || null,
|
|
323
|
-
name: name || null
|
|
324
|
-
};
|
|
337
|
+
return { path: result, name: result };
|
|
325
338
|
} catch (e) {
|
|
326
339
|
return { path: null, name: null };
|
|
327
340
|
}
|
package/src/sse-session.js
CHANGED
|
@@ -197,7 +197,7 @@ export class SseSession {
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
sendEndpoint(path) {
|
|
200
|
-
return this.
|
|
200
|
+
return this.sendEvent(SSE_EVENTS.ENDPOINT, path);
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
sendError(code, message, id = null) {
|
|
@@ -205,7 +205,7 @@ export class SseSession {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
sendPing() {
|
|
208
|
-
return this.
|
|
208
|
+
return this.sendEvent(SSE_EVENTS.PING, { timestamp: Date.now() });
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
sendProgress(current, total, message = '') {
|
|
@@ -213,7 +213,7 @@ export class SseSession {
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
sendCapabilities(capabilities) {
|
|
216
|
-
return this.
|
|
216
|
+
return this.sendEvent(SSE_EVENTS.CAPABILITIES, capabilities);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
sendResponse(jsonrpcResponse, id = null) {
|