@atlisp/mcp 1.7.0 → 1.8.1
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/atlisp-mcp.js +267 -43
- package/dist/cad-worker.js +73 -0
- package/package.json +1 -1
package/dist/atlisp-mcp.js
CHANGED
|
@@ -215,6 +215,7 @@ __export(cad_exports, {
|
|
|
215
215
|
cad: () => cad,
|
|
216
216
|
default: () => cad_default,
|
|
217
217
|
getWorker: () => getWorker,
|
|
218
|
+
onDocumentChanged: () => onDocumentChanged,
|
|
218
219
|
resetWorker: () => resetWorker,
|
|
219
220
|
sendMessage: () => sendMessage
|
|
220
221
|
});
|
|
@@ -222,6 +223,21 @@ import { spawn } from "child_process";
|
|
|
222
223
|
import path2 from "path";
|
|
223
224
|
import { fileURLToPath } from "url";
|
|
224
225
|
import { randomUUID } from "crypto";
|
|
226
|
+
function onDocumentChanged(callback) {
|
|
227
|
+
_docChangeCallbacks.push(callback);
|
|
228
|
+
}
|
|
229
|
+
function emitDocumentChanged(info) {
|
|
230
|
+
if (info.docName === _activeDocName)
|
|
231
|
+
return;
|
|
232
|
+
_activeDocName = info.docName || "";
|
|
233
|
+
for (const cb of _docChangeCallbacks) {
|
|
234
|
+
try {
|
|
235
|
+
cb(info);
|
|
236
|
+
} catch (e) {
|
|
237
|
+
console.error("doc change callback error:", e.message);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
225
241
|
function resetWorker() {
|
|
226
242
|
for (const [id, { reject, timeout }] of pendingRequests) {
|
|
227
243
|
clearTimeout(timeout);
|
|
@@ -285,6 +301,8 @@ function setupStdoutHandler(w) {
|
|
|
285
301
|
} else {
|
|
286
302
|
resolve(result);
|
|
287
303
|
}
|
|
304
|
+
} else if (result.type === "event" && result.eventType === "documentChanged") {
|
|
305
|
+
emitDocumentChanged({ docName: result.docName, docPath: result.docPath });
|
|
288
306
|
}
|
|
289
307
|
} catch (parseErr) {
|
|
290
308
|
console.error("JSON parse error in worker output:", parseErr.message);
|
|
@@ -337,6 +355,16 @@ function startHeartbeat() {
|
|
|
337
355
|
if (!result?.pong) {
|
|
338
356
|
console.error("heartbeat failed, worker may be dead");
|
|
339
357
|
resetWorker();
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (_platform) {
|
|
361
|
+
try {
|
|
362
|
+
const docResult = await sendMessage({ type: "getActiveDocInfo", platform: _platform });
|
|
363
|
+
if (docResult?.docName) {
|
|
364
|
+
emitDocumentChanged({ docName: docResult.docName, docPath: docResult.docPath || "" });
|
|
365
|
+
}
|
|
366
|
+
} catch (e) {
|
|
367
|
+
}
|
|
340
368
|
}
|
|
341
369
|
} catch (e) {
|
|
342
370
|
console.error("heartbeat error:", e.message);
|
|
@@ -365,7 +393,7 @@ function sendMessage(msg) {
|
|
|
365
393
|
}
|
|
366
394
|
});
|
|
367
395
|
}
|
|
368
|
-
var MESSAGE_TIMEOUT, HEARTBEAT_INTERVAL, MAX_RESTART_ATTEMPTS, RESTART_BACKOFF_BASE, __dirname, workerPath, worker, _platform, heartbeatTimer, pendingRequests, stdoutHandlerSetup, MAX_BUFFER_SIZE, restartCount, restartTimer, PRIORITY_NORMAL, CommandQueue, commandQueue, CadConnection, cad, cad_default;
|
|
396
|
+
var MESSAGE_TIMEOUT, HEARTBEAT_INTERVAL, MAX_RESTART_ATTEMPTS, RESTART_BACKOFF_BASE, __dirname, workerPath, worker, _platform, heartbeatTimer, pendingRequests, stdoutHandlerSetup, MAX_BUFFER_SIZE, restartCount, restartTimer, PRIORITY_NORMAL, MAX_QUEUE_SIZE, _docChangeCallbacks, _activeDocName, _monitorStarted, CommandQueue, commandQueue, CadConnection, cad, cad_default;
|
|
369
397
|
var init_cad = __esm({
|
|
370
398
|
"src/cad.js"() {
|
|
371
399
|
init_constants();
|
|
@@ -385,11 +413,20 @@ var init_cad = __esm({
|
|
|
385
413
|
restartCount = 0;
|
|
386
414
|
restartTimer = null;
|
|
387
415
|
PRIORITY_NORMAL = 1;
|
|
416
|
+
MAX_QUEUE_SIZE = 500;
|
|
417
|
+
_docChangeCallbacks = [];
|
|
418
|
+
_activeDocName = null;
|
|
419
|
+
_monitorStarted = false;
|
|
388
420
|
CommandQueue = class {
|
|
389
421
|
#queues = [[], [], []];
|
|
390
422
|
#processing = false;
|
|
391
423
|
#dedupMap = /* @__PURE__ */ new Map();
|
|
392
424
|
enqueue(command, priority = PRIORITY_NORMAL) {
|
|
425
|
+
const total = this.#queues.reduce((s, q) => s + q.length, 0);
|
|
426
|
+
if (total >= MAX_QUEUE_SIZE) {
|
|
427
|
+
command.reject(new Error("Command queue full, try again later"));
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
393
430
|
const dedupKey = this._dedupKey(command);
|
|
394
431
|
if (dedupKey) {
|
|
395
432
|
const existing = this.#dedupMap.get(dedupKey);
|
|
@@ -475,6 +512,13 @@ var init_cad = __esm({
|
|
|
475
512
|
this.product = result.platform;
|
|
476
513
|
_platform = result.platform;
|
|
477
514
|
this.connected = true;
|
|
515
|
+
_activeDocName = null;
|
|
516
|
+
if (!_monitorStarted) {
|
|
517
|
+
_monitorStarted = true;
|
|
518
|
+
sendMessage({ type: "startMonitor", platform: _platform }).catch(() => {
|
|
519
|
+
_monitorStarted = false;
|
|
520
|
+
});
|
|
521
|
+
}
|
|
478
522
|
return true;
|
|
479
523
|
}
|
|
480
524
|
} catch (e) {
|
|
@@ -563,6 +607,16 @@ var init_cad = __esm({
|
|
|
563
607
|
return false;
|
|
564
608
|
}
|
|
565
609
|
}
|
|
610
|
+
async getActiveDocInfo() {
|
|
611
|
+
if (!this.connected)
|
|
612
|
+
return { docName: "", docPath: "", docCount: 0 };
|
|
613
|
+
try {
|
|
614
|
+
const result = await sendMessage({ type: "getActiveDocInfo", platform: _platform });
|
|
615
|
+
return result || { docName: "", docPath: "", docCount: 0 };
|
|
616
|
+
} catch (e) {
|
|
617
|
+
return { docName: "", docPath: "", docCount: 0 };
|
|
618
|
+
}
|
|
619
|
+
}
|
|
566
620
|
async getInfo() {
|
|
567
621
|
if (!this.connected)
|
|
568
622
|
return "CAD \u672A\u8FDE\u63A5";
|
|
@@ -573,6 +627,8 @@ var init_cad = __esm({
|
|
|
573
627
|
this.version = null;
|
|
574
628
|
this.product = null;
|
|
575
629
|
_platform = null;
|
|
630
|
+
_activeDocName = null;
|
|
631
|
+
_monitorStarted = false;
|
|
576
632
|
commandQueue.clear();
|
|
577
633
|
resetWorker();
|
|
578
634
|
}
|
|
@@ -589,6 +645,8 @@ var init_cad = __esm({
|
|
|
589
645
|
this.version = null;
|
|
590
646
|
this.product = null;
|
|
591
647
|
_platform = null;
|
|
648
|
+
_activeDocName = null;
|
|
649
|
+
_monitorStarted = false;
|
|
592
650
|
commandQueue.clear();
|
|
593
651
|
resetWorker();
|
|
594
652
|
}
|
|
@@ -689,6 +747,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
689
747
|
// src/logger.js
|
|
690
748
|
init_config();
|
|
691
749
|
import fs2 from "fs";
|
|
750
|
+
import fsp from "fs/promises";
|
|
692
751
|
import path3 from "path";
|
|
693
752
|
import os2 from "os";
|
|
694
753
|
var DEBUG_FILE = config_default.debugFile || path3.join(os2.tmpdir(), "mcp-server-debug.log");
|
|
@@ -696,28 +755,33 @@ var MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
|
696
755
|
var MAX_LOG_FILES = 5;
|
|
697
756
|
var stream = null;
|
|
698
757
|
function rotateLog() {
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
stream
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
758
|
+
try {
|
|
759
|
+
if (!fs2.existsSync(DEBUG_FILE))
|
|
760
|
+
return;
|
|
761
|
+
const stat = fs2.statSync(DEBUG_FILE);
|
|
762
|
+
if (stat.size < MAX_LOG_SIZE)
|
|
763
|
+
return;
|
|
764
|
+
if (stream) {
|
|
765
|
+
stream.end();
|
|
766
|
+
stream = null;
|
|
767
|
+
}
|
|
768
|
+
for (let i = MAX_LOG_FILES - 1; i > 0; i--) {
|
|
769
|
+
const oldPath = `${DEBUG_FILE}.${i}`;
|
|
770
|
+
if (fs2.existsSync(oldPath)) {
|
|
771
|
+
try {
|
|
772
|
+
fs2.renameSync(oldPath, `${DEBUG_FILE}.${i + 1}`);
|
|
773
|
+
} catch (e) {
|
|
774
|
+
console.error("log rotate rename error:", e.message);
|
|
775
|
+
}
|
|
715
776
|
}
|
|
716
777
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
778
|
+
try {
|
|
779
|
+
fs2.renameSync(DEBUG_FILE, `${DEBUG_FILE}.1`);
|
|
780
|
+
} catch (e) {
|
|
781
|
+
console.error("log rotate rename error:", e.message);
|
|
782
|
+
}
|
|
783
|
+
} catch (e) {
|
|
784
|
+
console.error("log rotate error:", e.message);
|
|
721
785
|
}
|
|
722
786
|
}
|
|
723
787
|
function getStream() {
|
|
@@ -756,7 +820,90 @@ function closeLog() {
|
|
|
756
820
|
stream = null;
|
|
757
821
|
}
|
|
758
822
|
}
|
|
759
|
-
var
|
|
823
|
+
var requestStream = null;
|
|
824
|
+
var REQUEST_LOG_FILE = path3.join(os2.homedir(), "@lisp", "logs", "requests.log");
|
|
825
|
+
function ensureRequestLogDir() {
|
|
826
|
+
const dir = path3.dirname(REQUEST_LOG_FILE);
|
|
827
|
+
if (!fs2.existsSync(dir)) {
|
|
828
|
+
try {
|
|
829
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
830
|
+
} catch (e) {
|
|
831
|
+
console.error("request log mkdir error:", e.message);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
function rotateRequestLog() {
|
|
836
|
+
try {
|
|
837
|
+
if (!fs2.existsSync(REQUEST_LOG_FILE))
|
|
838
|
+
return;
|
|
839
|
+
const stat = fs2.statSync(REQUEST_LOG_FILE);
|
|
840
|
+
if (stat.size < 10 * 1024 * 1024)
|
|
841
|
+
return;
|
|
842
|
+
if (requestStream) {
|
|
843
|
+
requestStream.end();
|
|
844
|
+
requestStream = null;
|
|
845
|
+
}
|
|
846
|
+
for (let i = 5; i > 0; i--) {
|
|
847
|
+
const oldPath = `${REQUEST_LOG_FILE}.${i}`;
|
|
848
|
+
if (fs2.existsSync(oldPath)) {
|
|
849
|
+
try {
|
|
850
|
+
fs2.renameSync(oldPath, `${REQUEST_LOG_FILE}.${i + 1}`);
|
|
851
|
+
} catch (e) {
|
|
852
|
+
console.error("request log rotate error:", e.message);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
try {
|
|
857
|
+
fs2.renameSync(REQUEST_LOG_FILE, `${REQUEST_LOG_FILE}.1`);
|
|
858
|
+
} catch (e) {
|
|
859
|
+
console.error("request log rotate error:", e.message);
|
|
860
|
+
}
|
|
861
|
+
} catch (e) {
|
|
862
|
+
console.error("request log rotate error:", e.message);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
function logRequest(req) {
|
|
866
|
+
if (!config_default.requestLogEnabled)
|
|
867
|
+
return;
|
|
868
|
+
try {
|
|
869
|
+
ensureRequestLogDir();
|
|
870
|
+
rotateRequestLog();
|
|
871
|
+
if (!requestStream) {
|
|
872
|
+
requestStream = fs2.createWriteStream(REQUEST_LOG_FILE, { flags: "a" });
|
|
873
|
+
}
|
|
874
|
+
const entry = {
|
|
875
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
876
|
+
method: req.method,
|
|
877
|
+
path: req.path,
|
|
878
|
+
query: req.query,
|
|
879
|
+
ip: req.ip || req.connection?.remoteAddress,
|
|
880
|
+
userAgent: req.get("user-agent")
|
|
881
|
+
};
|
|
882
|
+
requestStream.write(JSON.stringify(entry) + "\n");
|
|
883
|
+
} catch (e) {
|
|
884
|
+
console.error("request log error:", e.message);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
function logResponse(req, res, duration) {
|
|
888
|
+
if (!config_default.requestLogEnabled)
|
|
889
|
+
return;
|
|
890
|
+
try {
|
|
891
|
+
ensureRequestLogDir();
|
|
892
|
+
if (!requestStream) {
|
|
893
|
+
requestStream = fs2.createWriteStream(REQUEST_LOG_FILE, { flags: "a" });
|
|
894
|
+
}
|
|
895
|
+
const entry = {
|
|
896
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
897
|
+
method: req.method,
|
|
898
|
+
path: req.path,
|
|
899
|
+
statusCode: res.statusCode,
|
|
900
|
+
duration: `${duration}ms`
|
|
901
|
+
};
|
|
902
|
+
requestStream.write(JSON.stringify(entry) + "\n");
|
|
903
|
+
} catch (e) {
|
|
904
|
+
console.error("request log error:", e.message);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
760
907
|
|
|
761
908
|
// src/handlers/resource-defs.js
|
|
762
909
|
import path4 from "path";
|
|
@@ -862,20 +1009,68 @@ init_config();
|
|
|
862
1009
|
import fs3 from "fs";
|
|
863
1010
|
import path5 from "path";
|
|
864
1011
|
|
|
1012
|
+
// src/errors.js
|
|
1013
|
+
var ERROR_CODES = {
|
|
1014
|
+
CAD_NOT_CONNECTED: "CAD_NOT_CONNECTED",
|
|
1015
|
+
CAD_BUSY: "CAD_BUSY",
|
|
1016
|
+
CAD_NO_DOCUMENT: "CAD_NO_DOCUMENT",
|
|
1017
|
+
LISP_PAREN_MISMATCH: "LISP_PAREN_MISMATCH",
|
|
1018
|
+
TIMEOUT: "TIMEOUT",
|
|
1019
|
+
INVALID_PARAMS: "INVALID_PARAMS",
|
|
1020
|
+
METHOD_NOT_FOUND: "METHOD_NOT_FOUND",
|
|
1021
|
+
RESOURCE_NOT_FOUND: "RESOURCE_NOT_FOUND",
|
|
1022
|
+
PACKAGE_NOT_FOUND: "PACKAGE_NOT_FOUND",
|
|
1023
|
+
INTERNAL_ERROR: "INTERNAL_ERROR"
|
|
1024
|
+
};
|
|
1025
|
+
var ERROR_MESSAGES = {
|
|
1026
|
+
[ERROR_CODES.CAD_NOT_CONNECTED]: "\u672A\u8FDE\u63A5 CAD\uFF0C\u8BF7\u5148\u8C03\u7528 connect_cad",
|
|
1027
|
+
[ERROR_CODES.CAD_BUSY]: "CAD \u5FD9\u788C\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
|
|
1028
|
+
[ERROR_CODES.CAD_NO_DOCUMENT]: "CAD \u4E2D\u6CA1\u6709\u6253\u5F00\u7684\u6587\u6863",
|
|
1029
|
+
[ERROR_CODES.LISP_PAREN_MISMATCH]: "LISP \u4EE3\u7801\u62EC\u53F7\u4E0D\u5339\u914D",
|
|
1030
|
+
[ERROR_CODES.TIMEOUT]: "\u64CD\u4F5C\u8D85\u65F6",
|
|
1031
|
+
[ERROR_CODES.INVALID_PARAMS]: "\u65E0\u6548\u7684\u53C2\u6570",
|
|
1032
|
+
[ERROR_CODES.METHOD_NOT_FOUND]: "\u65B9\u6CD5\u4E0D\u5B58\u5728",
|
|
1033
|
+
[ERROR_CODES.RESOURCE_NOT_FOUND]: "\u8D44\u6E90\u4E0D\u5B58\u5728",
|
|
1034
|
+
[ERROR_CODES.PACKAGE_NOT_FOUND]: "\u5305\u4E0D\u5B58\u5728",
|
|
1035
|
+
[ERROR_CODES.INTERNAL_ERROR]: "\u5185\u90E8\u9519\u8BEF"
|
|
1036
|
+
};
|
|
1037
|
+
var MCPError = class extends Error {
|
|
1038
|
+
constructor(code, message, details = {}) {
|
|
1039
|
+
super(message);
|
|
1040
|
+
this.code = code;
|
|
1041
|
+
this.details = details;
|
|
1042
|
+
this.name = "MCPError";
|
|
1043
|
+
}
|
|
1044
|
+
toJSON() {
|
|
1045
|
+
return {
|
|
1046
|
+
code: this.code,
|
|
1047
|
+
message: this.message,
|
|
1048
|
+
details: this.details
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
1052
|
+
function createError(code, details = {}) {
|
|
1053
|
+
const message = ERROR_MESSAGES[code] || ERROR_MESSAGES[ERROR_CODES.INTERNAL_ERROR];
|
|
1054
|
+
return new MCPError(code, message, details);
|
|
1055
|
+
}
|
|
1056
|
+
function mcpSuccessResponse(text) {
|
|
1057
|
+
return { content: [{ type: "text", text: String(text) }] };
|
|
1058
|
+
}
|
|
1059
|
+
|
|
865
1060
|
// src/handler-utils.js
|
|
866
|
-
init_cad();
|
|
867
1061
|
function mcpSuccess(text) {
|
|
868
|
-
return
|
|
1062
|
+
return mcpSuccessResponse(text);
|
|
869
1063
|
}
|
|
870
1064
|
function mcpError(text) {
|
|
871
1065
|
return { content: [{ type: "text", text: String(text) }], isError: true };
|
|
872
1066
|
}
|
|
873
1067
|
async function ensureCadConnected() {
|
|
874
|
-
|
|
875
|
-
|
|
1068
|
+
const { cad: cad2 } = await Promise.resolve().then(() => (init_cad(), cad_exports));
|
|
1069
|
+
if (!cad2.connected) {
|
|
1070
|
+
await cad2.connect();
|
|
876
1071
|
}
|
|
877
|
-
if (!
|
|
878
|
-
throw
|
|
1072
|
+
if (!cad2.connected) {
|
|
1073
|
+
throw createError(ERROR_CODES.CAD_NOT_CONNECTED);
|
|
879
1074
|
}
|
|
880
1075
|
}
|
|
881
1076
|
function escapeLispString(str) {
|
|
@@ -2610,7 +2805,9 @@ import {
|
|
|
2610
2805
|
ListPromptsRequestSchema,
|
|
2611
2806
|
GetPromptRequestSchema,
|
|
2612
2807
|
ListRootsRequestSchema,
|
|
2613
|
-
CreateMessageRequestSchema
|
|
2808
|
+
CreateMessageRequestSchema,
|
|
2809
|
+
CompleteRequestSchema,
|
|
2810
|
+
PingRequestSchema
|
|
2614
2811
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
2615
2812
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2616
2813
|
|
|
@@ -3122,12 +3319,11 @@ var RESOURCE_TEMPLATES = [
|
|
|
3122
3319
|
}
|
|
3123
3320
|
];
|
|
3124
3321
|
var SERVER_CAPABILITIES = {
|
|
3125
|
-
tools: {
|
|
3126
|
-
resources: { subscribe: true, listChanged: true
|
|
3322
|
+
tools: { listChanged: true },
|
|
3323
|
+
resources: { subscribe: true, listChanged: true },
|
|
3127
3324
|
prompts: {},
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
logging: {}
|
|
3325
|
+
logging: {},
|
|
3326
|
+
completions: {}
|
|
3131
3327
|
};
|
|
3132
3328
|
function createMcpServer(handlers = {}) {
|
|
3133
3329
|
const { tools: tools18 = [], handleToolCall: handleToolCall2 = () => ({ content: [] }) } = handlers;
|
|
@@ -3202,15 +3398,27 @@ function createMcpServer(handlers = {}) {
|
|
|
3202
3398
|
}));
|
|
3203
3399
|
server.setRequestHandler(CreateMessageRequestSchema, async (request) => {
|
|
3204
3400
|
const { message } = request.params;
|
|
3205
|
-
|
|
3401
|
+
log("Sampling request received", { text: message.content?.[0]?.text });
|
|
3206
3402
|
return {
|
|
3207
3403
|
content: [{
|
|
3208
3404
|
type: "text",
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3405
|
+
text: "[sampling] LLM integration not configured; returning original message"
|
|
3406
|
+
}],
|
|
3407
|
+
model: "default",
|
|
3408
|
+
role: "assistant"
|
|
3409
|
+
};
|
|
3410
|
+
});
|
|
3411
|
+
server.setRequestHandler(CompleteRequestSchema, async (request) => {
|
|
3412
|
+
const { argument, ref } = request.params;
|
|
3413
|
+
return {
|
|
3414
|
+
completion: {
|
|
3415
|
+
values: [],
|
|
3416
|
+
hasMore: false,
|
|
3417
|
+
total: 0
|
|
3418
|
+
}
|
|
3212
3419
|
};
|
|
3213
3420
|
});
|
|
3421
|
+
server.setRequestHandler(PingRequestSchema, async () => ({ pong: true }));
|
|
3214
3422
|
return server;
|
|
3215
3423
|
}
|
|
3216
3424
|
|
|
@@ -8696,8 +8904,8 @@ function setupRoutes(app) {
|
|
|
8696
8904
|
app.use((req, res, next) => {
|
|
8697
8905
|
const start = Date.now();
|
|
8698
8906
|
res.on("finish", () => {
|
|
8699
|
-
|
|
8700
|
-
|
|
8907
|
+
logRequest(req);
|
|
8908
|
+
logResponse(req, res, Date.now() - start);
|
|
8701
8909
|
});
|
|
8702
8910
|
next();
|
|
8703
8911
|
});
|
|
@@ -8735,7 +8943,7 @@ function setupRoutes(app) {
|
|
|
8735
8943
|
},
|
|
8736
8944
|
mcp: {
|
|
8737
8945
|
sessions: sessionServers.size,
|
|
8738
|
-
tools:
|
|
8946
|
+
tools: tools17.length
|
|
8739
8947
|
}
|
|
8740
8948
|
});
|
|
8741
8949
|
});
|
|
@@ -8791,7 +8999,7 @@ function setupRoutes(app) {
|
|
|
8791
8999
|
<h1>@lisp MCP Server API</h1>
|
|
8792
9000
|
<div class="info">
|
|
8793
9001
|
<strong>Version:</strong> 1.6.0 |
|
|
8794
|
-
<strong>Tools:</strong>
|
|
9002
|
+
<strong>Tools:</strong> ${tools17.length} |
|
|
8795
9003
|
<strong>Resources:</strong> 11
|
|
8796
9004
|
</div>
|
|
8797
9005
|
|
|
@@ -8917,7 +9125,7 @@ curl -X POST http://localhost:8110/mcp \\
|
|
|
8917
9125
|
</table>
|
|
8918
9126
|
</div>
|
|
8919
9127
|
|
|
8920
|
-
<h2>Tools (${
|
|
9128
|
+
<h2>Tools (${tools17.length})</h2>
|
|
8921
9129
|
<div class="card">
|
|
8922
9130
|
<p>Use <code>tools/list</code> MCP method to get full tool list.</p>
|
|
8923
9131
|
</div>
|
|
@@ -9172,6 +9380,22 @@ async function startServer() {
|
|
|
9172
9380
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
9173
9381
|
}
|
|
9174
9382
|
}
|
|
9383
|
+
onDocumentChanged((info) => {
|
|
9384
|
+
const uris = [
|
|
9385
|
+
"atlisp://dwg/name",
|
|
9386
|
+
"atlisp://dwg/path",
|
|
9387
|
+
"atlisp://cad/dwgs",
|
|
9388
|
+
"atlisp://dwg/tbl",
|
|
9389
|
+
"atlisp://dwg/entities",
|
|
9390
|
+
"atlisp://dwg/block-refs",
|
|
9391
|
+
"atlisp://dwg/text-content",
|
|
9392
|
+
"atlisp://dwg/groups"
|
|
9393
|
+
];
|
|
9394
|
+
for (const uri of uris) {
|
|
9395
|
+
clearCache(uri);
|
|
9396
|
+
notify(uri, { docName: info.docName, docPath: info.docPath });
|
|
9397
|
+
}
|
|
9398
|
+
});
|
|
9175
9399
|
if (!process.env.VITEST) {
|
|
9176
9400
|
await startServer();
|
|
9177
9401
|
}
|
package/dist/cad-worker.js
CHANGED
|
@@ -245,6 +245,63 @@ string encoding = d.encoding != null ? d.encoding.ToString() : "";
|
|
|
245
245
|
}
|
|
246
246
|
*/});
|
|
247
247
|
|
|
248
|
+
const cadGetActiveDocInfo = edge.func(function() {/*
|
|
249
|
+
async (input) => {
|
|
250
|
+
try {
|
|
251
|
+
string platform = input.ToString();
|
|
252
|
+
string progId = platform == "BricsCAD" ? "BricscadApp.AcadApplication" : platform + ".Application";
|
|
253
|
+
dynamic cad = System.Runtime.InteropServices.Marshal.GetActiveObject(progId);
|
|
254
|
+
if (cad != null) {
|
|
255
|
+
int docCount = cad.Documents.Count;
|
|
256
|
+
string docName = "";
|
|
257
|
+
string docPath = "";
|
|
258
|
+
try {
|
|
259
|
+
docName = cad.ActiveDocument.Name;
|
|
260
|
+
docPath = cad.ActiveDocument.FullName;
|
|
261
|
+
} catch {}
|
|
262
|
+
return new { hasDoc = docCount > 0, docCount = docCount, docName = docName, docPath = docPath };
|
|
263
|
+
}
|
|
264
|
+
} catch (Exception ex) {
|
|
265
|
+
System.Diagnostics.Debug.WriteLine("cadGetActiveDocInfo error: " + ex.Message);
|
|
266
|
+
}
|
|
267
|
+
return new { hasDoc = false, docCount = 0, docName = "", docPath = "" };
|
|
268
|
+
}
|
|
269
|
+
*/});
|
|
270
|
+
|
|
271
|
+
const cadStartMonitor = edge.func(function() {/*
|
|
272
|
+
async (input) => {
|
|
273
|
+
try {
|
|
274
|
+
string platform = input.ToString();
|
|
275
|
+
string progId = platform == "BricsCAD" ? "BricscadApp.AcadApplication" : platform + ".Application";
|
|
276
|
+
dynamic cad = System.Runtime.InteropServices.Marshal.GetActiveObject(progId);
|
|
277
|
+
if (cad == null) return new { success = false, error = "CAD not found" };
|
|
278
|
+
|
|
279
|
+
string prevName = "";
|
|
280
|
+
var timer = new System.Threading.Timer((_) => {
|
|
281
|
+
try {
|
|
282
|
+
string docName = cad.ActiveDocument.Name;
|
|
283
|
+
if (docName != prevName) {
|
|
284
|
+
prevName = docName;
|
|
285
|
+
string docPath = "";
|
|
286
|
+
try { docPath = cad.ActiveDocument.FullName; } catch {}
|
|
287
|
+
string json = "{\"type\":\"event\",\"eventType\":\"documentChanged\",\"docName\":\"" +
|
|
288
|
+
docName.Replace("\\", "\\\\").Replace("\"", "\\\"") +
|
|
289
|
+
"\",\"docPath\":\"" +
|
|
290
|
+
docPath.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"}";
|
|
291
|
+
Console.WriteLine(json);
|
|
292
|
+
}
|
|
293
|
+
} catch (Exception ex) {
|
|
294
|
+
System.Diagnostics.Debug.WriteLine("cadMonitor timer error: " + ex.Message);
|
|
295
|
+
}
|
|
296
|
+
}, null, 3000, 3000);
|
|
297
|
+
|
|
298
|
+
return new { success = true };
|
|
299
|
+
} catch (Exception ex) {
|
|
300
|
+
return new { success = false, error = ex.Message };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
*/});
|
|
304
|
+
|
|
248
305
|
process.stdin.setEncoding('utf8');
|
|
249
306
|
|
|
250
307
|
let stdinBuffer = '';
|
|
@@ -581,5 +638,21 @@ async function handleMessage(msg) {
|
|
|
581
638
|
});
|
|
582
639
|
});
|
|
583
640
|
}
|
|
641
|
+
if (msg.type === 'getActiveDocInfo') {
|
|
642
|
+
return new Promise((resolve, reject) => {
|
|
643
|
+
cadGetActiveDocInfo(msg.platform || 'AutoCAD', (e, r) => {
|
|
644
|
+
if (e) reject(e);
|
|
645
|
+
else resolve(r);
|
|
646
|
+
});
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
if (msg.type === 'startMonitor') {
|
|
650
|
+
return new Promise((resolve, reject) => {
|
|
651
|
+
cadStartMonitor(msg.platform || 'AutoCAD', (e, r) => {
|
|
652
|
+
if (e) reject(e);
|
|
653
|
+
else resolve(r);
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
}
|
|
584
657
|
return { error: 'unknown message type' };
|
|
585
658
|
}
|