@atlisp/mcp 1.0.7 → 1.0.8

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/package.json +1 -1
  2. package/src/index.js +58 -44
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlisp/mcp",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "MCP Server for @lisp on CAD",
5
5
  "type": "module",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  import fs from 'fs';
9
9
  import path from 'path';
10
10
  import os from 'os';
11
+ import crypto from 'crypto';
11
12
  import { cad } from './cad.js';
12
13
 
13
14
  const DEBUG_FILE = path.join(os.tmpdir(), 'mcp-server-debug.log');
@@ -221,21 +222,6 @@ async function handleToolCall(name, args) {
221
222
  }
222
223
  }
223
224
 
224
- const mcpServer = new Server(
225
- { name: 'atlisp-mcp-server', version: '1.0.7' },
226
- { capabilities: { tools: {} } }
227
- );
228
-
229
- mcpServer.setRequestHandler(ListToolsRequestSchema, async () => {
230
- return { tools };
231
- });
232
-
233
- mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
234
- console.error('setRequestHandler called, name:', request.params.name);
235
- const { name, arguments: args } = request.params;
236
- return await handleToolCall(name, args || {});
237
- });
238
-
239
225
  async function initCadConnection() {
240
226
  log('Attempting to connect to CAD on startup...');
241
227
  try {
@@ -251,8 +237,25 @@ async function initCadConnection() {
251
237
  }
252
238
  }
253
239
 
240
+ function createMcpServer() {
241
+ const server = new Server(
242
+ { name: 'atlisp-mcp-server', version: '1.0.8' },
243
+ { capabilities: { tools: {} } }
244
+ );
245
+
246
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
247
+
248
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
249
+ const { name, arguments: args } = request.params;
250
+ return await handleToolCall(name, args || {});
251
+ });
252
+
253
+ return server;
254
+ }
255
+
254
256
  if (TRANSPORT === 'stdio') {
255
257
  await initCadConnection();
258
+ const mcpServer = createMcpServer();
256
259
  const transport = new StdioServerTransport();
257
260
  await mcpServer.connect(transport);
258
261
  console.error('@lisp MCP Server 运行在 stdio 模式');
@@ -261,59 +264,71 @@ if (TRANSPORT === 'stdio') {
261
264
  app.use(express.json({ type: ['application/json', 'application/json-rpc'] }));
262
265
 
263
266
  app.get('/health', (req, res) => {
264
- res.json({ status: 'ok', cad: cad.connected ? 'connected' : 'disconnected' });
267
+ return res.json({ status: 'ok', cad: cad.connected ? 'connected' : 'disconnected' });
265
268
  });
266
269
 
270
+ let mcpServer = null;
271
+ const sessionId = crypto.randomUUID();
272
+
267
273
  app.post('/mcp', async (req, res) => {
268
- log('POST /mcp called, body: ' + JSON.stringify(req.body));
269
- try {
270
- const message = req.body;
271
- const id = message.id;
274
+ if (!mcpServer) {
275
+ mcpServer = createMcpServer();
276
+ }
272
277
 
273
- if (!id) {
274
- log('No id, returning 204');
275
- return res.status(204).end();
276
- }
278
+ const { method, params, id } = req.body || {};
279
+
280
+ res.setHeader('Content-Type', 'application/json');
281
+ res.setHeader('mcp-session-id', sessionId);
277
282
 
278
- if (message.method === 'initialize') {
283
+ if (!id) {
284
+ return res.status(204).end();
285
+ }
286
+
287
+ try {
288
+ if (method === 'initialize') {
279
289
  return res.json({
280
290
  jsonrpc: '2.0',
281
- id: id,
291
+ id,
282
292
  result: {
283
293
  protocolVersion: '2024-11-05',
284
294
  capabilities: { tools: {} },
285
- serverInfo: { name: 'atlisp-mcp-server', version: '1.0.7' }
295
+ serverInfo: { name: 'atlisp-mcp-server', version: '1.0.8' }
286
296
  }
287
297
  });
288
298
  }
289
299
 
290
- if (message.method === 'tools/list') {
300
+ if (method === 'tools/list') {
291
301
  return res.json({
292
302
  jsonrpc: '2.0',
293
- id: id,
303
+ id,
294
304
  result: { tools }
295
305
  });
296
306
  }
297
307
 
298
- if (message.method === 'tools/call') {
299
- log('tools/call called, name: ' + message.params.name);
300
- const result = await handleToolCall(message.params.name, message.params.arguments || {});
301
- log('tools/call result: ' + JSON.stringify(result));
302
- return res.json({
303
- jsonrpc: '2.0',
304
- id: id,
305
- result
306
- });
308
+ if (method === 'tools/call') {
309
+ const toolName = params?.name;
310
+ if (!toolName) {
311
+ return res.json({
312
+ jsonrpc: '2.0',
313
+ id,
314
+ error: { code: -32602, message: 'Invalid params: missing tool name' }
315
+ });
316
+ }
317
+ const toolArgs = params?.arguments || {};
318
+ const result = await handleToolCall(toolName, toolArgs);
319
+ return res.json({ jsonrpc: '2.0', id, result });
307
320
  }
308
321
 
309
- res.json({
322
+ return res.json({
310
323
  jsonrpc: '2.0',
311
- id: id,
324
+ id,
312
325
  error: { code: -32601, message: 'Method not found' }
313
326
  });
314
327
  } catch (e) {
315
- res.status(500).json({
328
+ log('MCP error: ' + e.message);
329
+ return res.status(500).json({
316
330
  jsonrpc: '2.0',
331
+ id,
317
332
  error: { code: -32603, message: e.message }
318
333
  });
319
334
  }
@@ -321,7 +336,6 @@ if (TRANSPORT === 'stdio') {
321
336
 
322
337
  app.listen(PORT, HOST, async () => {
323
338
  await initCadConnection();
324
- const status = cad.connected ? '已连接 CAD' : '未连接 CAD';
325
- console.error(`@lisp MCP Server 启动 - http://${HOST}:${PORT} - ${status}`);
339
+ console.error(`@lisp MCP Server 启动 - http://${HOST}:${PORT} - Streamable HTTP`);
326
340
  });
327
- }
341
+ }