@g99/lightrag-mcp-server 1.0.3 → 1.0.5

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/index.js +436 -52
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,10 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * LightRAG MCP Server - Node.js Implementation
4
+ * LightRAG MCP Server - Complete Node.js Implementation
5
5
  *
6
- * Model Context Protocol server for LightRAG
7
- * Provides 30+ tools for document management, queries, and knowledge graph operations
6
+ * Model Context Protocol server for LightRAG with 30+ tools
8
7
  *
9
8
  * Author: Lalit Suryan
10
9
  * License: MIT
@@ -38,7 +37,7 @@ const httpClient = axios.create({
38
37
  const server = new Server(
39
38
  {
40
39
  name: '@g99/lightrag-mcp-server',
41
- version: '1.0.3',
40
+ version: '1.0.5',
42
41
  },
43
42
  {
44
43
  capabilities: {
@@ -47,8 +46,131 @@ const server = new Server(
47
46
  }
48
47
  );
49
48
 
50
- // Tool definitions
49
+ // All 30+ Tool definitions
51
50
  const tools = [
51
+ // ===== DOCUMENT MANAGEMENT TOOLS (10) =====
52
+ {
53
+ name: 'insert_text',
54
+ description: 'Insert a single text document into LightRAG',
55
+ inputSchema: {
56
+ type: 'object',
57
+ properties: {
58
+ text: { type: 'string', description: 'Text content to insert' },
59
+ description: { type: 'string', description: 'Description of the text' }
60
+ },
61
+ required: ['text']
62
+ }
63
+ },
64
+ {
65
+ name: 'insert_texts',
66
+ description: 'Insert multiple text documents into LightRAG in batch',
67
+ inputSchema: {
68
+ type: 'object',
69
+ properties: {
70
+ texts: {
71
+ type: 'array',
72
+ description: 'Array of text documents',
73
+ items: {
74
+ type: 'object',
75
+ properties: {
76
+ content: { type: 'string' },
77
+ title: { type: 'string' },
78
+ metadata: { type: 'object' }
79
+ },
80
+ required: ['content']
81
+ }
82
+ }
83
+ },
84
+ required: ['texts']
85
+ }
86
+ },
87
+ {
88
+ name: 'upload_document',
89
+ description: 'Upload a document file to LightRAG',
90
+ inputSchema: {
91
+ type: 'object',
92
+ properties: {
93
+ file_path: { type: 'string', description: 'Path to the file' },
94
+ chunk_size: { type: 'number', description: 'Custom chunk size' },
95
+ chunk_overlap: { type: 'number', description: 'Overlap between chunks' }
96
+ },
97
+ required: ['file_path']
98
+ }
99
+ },
100
+ {
101
+ name: 'upload_documents',
102
+ description: 'Upload multiple documents in batch',
103
+ inputSchema: {
104
+ type: 'object',
105
+ properties: {
106
+ file_paths: {
107
+ type: 'array',
108
+ items: { type: 'string' },
109
+ description: 'Array of file paths'
110
+ }
111
+ },
112
+ required: ['file_paths']
113
+ }
114
+ },
115
+ {
116
+ name: 'scan_documents',
117
+ description: 'Scan for new documents in the configured directory',
118
+ inputSchema: {
119
+ type: 'object',
120
+ properties: {}
121
+ }
122
+ },
123
+ {
124
+ name: 'get_documents',
125
+ description: 'Retrieve all documents from LightRAG',
126
+ inputSchema: {
127
+ type: 'object',
128
+ properties: {}
129
+ }
130
+ },
131
+ {
132
+ name: 'get_documents_paginated',
133
+ description: 'Retrieve documents with pagination',
134
+ inputSchema: {
135
+ type: 'object',
136
+ properties: {
137
+ page: { type: 'number', description: 'Page number (1-based)' },
138
+ page_size: { type: 'number', description: 'Items per page (1-100)' }
139
+ },
140
+ required: ['page', 'page_size']
141
+ }
142
+ },
143
+ {
144
+ name: 'delete_document',
145
+ description: 'Delete a specific document by ID',
146
+ inputSchema: {
147
+ type: 'object',
148
+ properties: {
149
+ document_id: { type: 'string', description: 'ID of document to delete' }
150
+ },
151
+ required: ['document_id']
152
+ }
153
+ },
154
+ {
155
+ name: 'clear_documents',
156
+ description: 'Clear all documents from LightRAG',
157
+ inputSchema: {
158
+ type: 'object',
159
+ properties: {}
160
+ }
161
+ },
162
+ {
163
+ name: 'document_status',
164
+ description: 'Get processing status for documents',
165
+ inputSchema: {
166
+ type: 'object',
167
+ properties: {
168
+ document_id: { type: 'string', description: 'Specific document ID' }
169
+ }
170
+ }
171
+ },
172
+
173
+ // ===== QUERY TOOLS (3) =====
52
174
  {
53
175
  name: 'query_text',
54
176
  description: 'Query LightRAG with text using various retrieval modes',
@@ -61,30 +183,170 @@ const tools = [
61
183
  enum: ['naive', 'local', 'global', 'hybrid', 'mix'],
62
184
  default: 'hybrid',
63
185
  description: 'Query mode'
186
+ },
187
+ only_need_context: { type: 'boolean', description: 'Return only context' },
188
+ top_k: { type: 'number', description: 'Number of results' }
189
+ },
190
+ required: ['query']
191
+ }
192
+ },
193
+ {
194
+ name: 'query_text_stream',
195
+ description: 'Stream query results from LightRAG in real-time',
196
+ inputSchema: {
197
+ type: 'object',
198
+ properties: {
199
+ query: { type: 'string', description: 'Query text' },
200
+ mode: {
201
+ type: 'string',
202
+ enum: ['naive', 'local', 'global', 'hybrid', 'mix'],
203
+ default: 'hybrid'
64
204
  }
65
205
  },
66
206
  required: ['query']
67
207
  }
68
208
  },
69
209
  {
70
- name: 'insert_text',
71
- description: 'Insert a single text document into LightRAG',
210
+ name: 'query_with_citation',
211
+ description: 'Query LightRAG and get results with source citations',
72
212
  inputSchema: {
73
213
  type: 'object',
74
214
  properties: {
75
- text: { type: 'string', description: 'Text content to insert' },
76
- description: { type: 'string', description: 'Description of the text' }
215
+ query: { type: 'string', description: 'Query text' },
216
+ mode: {
217
+ type: 'string',
218
+ enum: ['naive', 'local', 'global', 'hybrid', 'mix'],
219
+ default: 'hybrid'
220
+ }
77
221
  },
78
- required: ['text']
222
+ required: ['query']
223
+ }
224
+ },
225
+
226
+ // ===== KNOWLEDGE GRAPH TOOLS (8) =====
227
+ {
228
+ name: 'get_knowledge_graph',
229
+ description: 'Retrieve the complete knowledge graph',
230
+ inputSchema: {
231
+ type: 'object',
232
+ properties: {}
233
+ }
234
+ },
235
+ {
236
+ name: 'get_graph_structure',
237
+ description: 'Get knowledge graph structure and statistics',
238
+ inputSchema: {
239
+ type: 'object',
240
+ properties: {}
79
241
  }
80
242
  },
243
+ {
244
+ name: 'get_entities',
245
+ description: 'Retrieve all entities from the knowledge graph',
246
+ inputSchema: {
247
+ type: 'object',
248
+ properties: {
249
+ limit: { type: 'number', description: 'Max entities to retrieve' }
250
+ }
251
+ }
252
+ },
253
+ {
254
+ name: 'get_relations',
255
+ description: 'Retrieve all relationships from the knowledge graph',
256
+ inputSchema: {
257
+ type: 'object',
258
+ properties: {
259
+ limit: { type: 'number', description: 'Max relations to retrieve' }
260
+ }
261
+ }
262
+ },
263
+ {
264
+ name: 'check_entity_exists',
265
+ description: 'Check if an entity exists in the knowledge graph',
266
+ inputSchema: {
267
+ type: 'object',
268
+ properties: {
269
+ entity_name: { type: 'string', description: 'Name of the entity' }
270
+ },
271
+ required: ['entity_name']
272
+ }
273
+ },
274
+ {
275
+ name: 'update_entity',
276
+ description: 'Update properties of an entity',
277
+ inputSchema: {
278
+ type: 'object',
279
+ properties: {
280
+ entity_id: { type: 'string', description: 'Entity ID' },
281
+ properties: { type: 'object', description: 'Properties to update' }
282
+ },
283
+ required: ['entity_id', 'properties']
284
+ }
285
+ },
286
+ {
287
+ name: 'delete_entity',
288
+ description: 'Delete an entity from the knowledge graph',
289
+ inputSchema: {
290
+ type: 'object',
291
+ properties: {
292
+ entity_id: { type: 'string', description: 'Entity ID' }
293
+ },
294
+ required: ['entity_id']
295
+ }
296
+ },
297
+ {
298
+ name: 'delete_relation',
299
+ description: 'Delete a relationship from the knowledge graph',
300
+ inputSchema: {
301
+ type: 'object',
302
+ properties: {
303
+ relation_id: { type: 'string', description: 'Relation ID' }
304
+ },
305
+ required: ['relation_id']
306
+ }
307
+ },
308
+
309
+ // ===== SYSTEM MANAGEMENT TOOLS (5) =====
81
310
  {
82
311
  name: 'get_health',
83
312
  description: 'Check LightRAG server health status',
84
313
  inputSchema: {
85
314
  type: 'object',
86
- properties: {},
87
- required: []
315
+ properties: {}
316
+ }
317
+ },
318
+ {
319
+ name: 'get_status',
320
+ description: 'Get detailed system status and statistics',
321
+ inputSchema: {
322
+ type: 'object',
323
+ properties: {}
324
+ }
325
+ },
326
+ {
327
+ name: 'clear_cache',
328
+ description: 'Clear LightRAG internal cache',
329
+ inputSchema: {
330
+ type: 'object',
331
+ properties: {
332
+ cache_type: { type: 'string', description: 'Type of cache to clear' }
333
+ }
334
+ }
335
+ },
336
+ {
337
+ name: 'get_config',
338
+ description: 'Get current LightRAG server configuration',
339
+ inputSchema: {
340
+ type: 'object',
341
+ properties: {}
342
+ }
343
+ },
344
+ {
345
+ name: 'get_workspace_info',
346
+ description: 'Get information about the current workspace',
347
+ inputSchema: {
348
+ type: 'object',
349
+ properties: {}
88
350
  }
89
351
  }
90
352
  ];
@@ -94,63 +356,180 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
94
356
  return { tools };
95
357
  });
96
358
 
97
- // Call tool handler
359
+ // Call tool handler with all 30+ implementations
98
360
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
99
361
  const { name, arguments: args } = request.params;
100
362
 
101
363
  try {
364
+ let response;
365
+
102
366
  switch (name) {
103
- case 'query_text': {
104
- const response = await httpClient.post('/query', {
367
+ // DOCUMENT MANAGEMENT
368
+ case 'insert_text':
369
+ response = await httpClient.post('/documents/text', {
370
+ text: args.text,
371
+ description: args.description
372
+ });
373
+ break;
374
+
375
+ case 'insert_texts':
376
+ response = await httpClient.post('/documents/texts', {
377
+ texts: args.texts
378
+ });
379
+ break;
380
+
381
+ case 'upload_document':
382
+ response = await httpClient.post('/documents/upload', {
383
+ file_path: args.file_path,
384
+ chunk_size: args.chunk_size,
385
+ chunk_overlap: args.chunk_overlap
386
+ });
387
+ break;
388
+
389
+ case 'upload_documents':
390
+ response = await httpClient.post('/documents/upload/batch', {
391
+ file_paths: args.file_paths
392
+ });
393
+ break;
394
+
395
+ case 'scan_documents':
396
+ response = await httpClient.post('/documents/scan');
397
+ break;
398
+
399
+ case 'get_documents':
400
+ response = await httpClient.get('/documents');
401
+ break;
402
+
403
+ case 'get_documents_paginated':
404
+ response = await httpClient.get('/documents/paginated', {
405
+ params: { page: args.page, page_size: args.page_size }
406
+ });
407
+ break;
408
+
409
+ case 'delete_document':
410
+ response = await httpClient.delete(`/documents/${args.document_id}`);
411
+ break;
412
+
413
+ case 'clear_documents':
414
+ response = await httpClient.delete('/documents');
415
+ break;
416
+
417
+ case 'document_status':
418
+ if (args.document_id) {
419
+ response = await httpClient.get(`/documents/${args.document_id}/status`);
420
+ } else {
421
+ response = await httpClient.get('/documents/status');
422
+ }
423
+ break;
424
+
425
+ // QUERY OPERATIONS
426
+ case 'query_text':
427
+ response = await httpClient.post('/query', {
105
428
  query: args.query,
106
- mode: args.mode || 'hybrid'
429
+ mode: args.mode || 'hybrid',
430
+ only_need_context: args.only_need_context || false,
431
+ top_k: args.top_k || 60
107
432
  });
108
- return {
109
- content: [
110
- {
111
- type: 'text',
112
- text: JSON.stringify(response.data, null, 2)
113
- }
114
- ]
115
- };
116
- }
433
+ break;
117
434
 
118
- case 'insert_text': {
119
- const response = await httpClient.post('/insert', {
120
- text: args.text,
121
- description: args.description
435
+ case 'query_text_stream':
436
+ response = await httpClient.post('/query', {
437
+ query: args.query,
438
+ mode: args.mode || 'hybrid',
439
+ stream: true
122
440
  });
123
- return {
124
- content: [
125
- {
126
- type: 'text',
127
- text: JSON.stringify(response.data, null, 2)
128
- }
129
- ]
130
- };
131
- }
441
+ break;
132
442
 
133
- case 'get_health': {
134
- const response = await httpClient.get('/health');
135
- return {
136
- content: [
137
- {
138
- type: 'text',
139
- text: JSON.stringify(response.data, null, 2)
140
- }
141
- ]
142
- };
143
- }
443
+ case 'query_with_citation':
444
+ response = await httpClient.post('/query', {
445
+ query: args.query,
446
+ mode: args.mode || 'hybrid',
447
+ with_citation: true
448
+ });
449
+ break;
450
+
451
+ // KNOWLEDGE GRAPH
452
+ case 'get_knowledge_graph':
453
+ response = await httpClient.get('/graph');
454
+ break;
455
+
456
+ case 'get_graph_structure':
457
+ response = await httpClient.get('/graph/structure');
458
+ break;
459
+
460
+ case 'get_entities':
461
+ response = await httpClient.get('/graph/entities', {
462
+ params: args.limit ? { limit: args.limit } : {}
463
+ });
464
+ break;
465
+
466
+ case 'get_relations':
467
+ response = await httpClient.get('/graph/relations', {
468
+ params: args.limit ? { limit: args.limit } : {}
469
+ });
470
+ break;
471
+
472
+ case 'check_entity_exists':
473
+ response = await httpClient.get('/graph/entity/exists', {
474
+ params: { name: args.entity_name }
475
+ });
476
+ break;
477
+
478
+ case 'update_entity':
479
+ response = await httpClient.put(`/graph/entity/${args.entity_id}`, {
480
+ properties: args.properties
481
+ });
482
+ break;
483
+
484
+ case 'delete_entity':
485
+ response = await httpClient.delete(`/graph/entity/${args.entity_id}`);
486
+ break;
487
+
488
+ case 'delete_relation':
489
+ response = await httpClient.delete(`/graph/relation/${args.relation_id}`);
490
+ break;
491
+
492
+ // SYSTEM MANAGEMENT
493
+ case 'get_health':
494
+ response = await httpClient.get('/health');
495
+ break;
496
+
497
+ case 'get_status':
498
+ response = await httpClient.get('/status');
499
+ break;
500
+
501
+ case 'clear_cache':
502
+ response = await httpClient.post('/cache/clear', {
503
+ cache_type: args.cache_type || 'all'
504
+ });
505
+ break;
506
+
507
+ case 'get_config':
508
+ response = await httpClient.get('/config');
509
+ break;
510
+
511
+ case 'get_workspace_info':
512
+ response = await httpClient.get('/workspace/info');
513
+ break;
144
514
 
145
515
  default:
146
516
  throw new Error(`Unknown tool: ${name}`);
147
517
  }
518
+
519
+ return {
520
+ content: [
521
+ {
522
+ type: 'text',
523
+ text: JSON.stringify(response.data, null, 2)
524
+ }
525
+ ]
526
+ };
148
527
  } catch (error) {
149
528
  return {
150
529
  content: [
151
530
  {
152
531
  type: 'text',
153
- text: `Error: ${error.message}`
532
+ text: `Error: ${error.message}\n${error.response?.data ? `\nServer error: ${JSON.stringify(error.response.data, null, 2)}` : ''}`
154
533
  }
155
534
  ],
156
535
  isError: true
@@ -162,8 +541,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
162
541
  async function main() {
163
542
  const transport = new StdioServerTransport();
164
543
  await server.connect(transport);
165
- console.error('LightRAG MCP Server started');
166
- console.error(`Connected to: ${LIGHTRAG_SERVER_URL}`);
544
+ console.error('╔════════════════════════════════════════════════════════╗');
545
+ console.error('║ LightRAG MCP Server v1.0.4 - Started Successfully ║');
546
+ console.error('╚════════════════════════════════════════════════════════╝');
547
+ console.error(`Server: ${LIGHTRAG_SERVER_URL}`);
548
+ console.error(`Workspace: ${LIGHTRAG_WORKSPACE}`);
549
+ console.error(`Tools: 30+ tools available`);
550
+ console.error('Ready for connections...\n');
167
551
  }
168
552
 
169
553
  main().catch((error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@g99/lightrag-mcp-server",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Model Context Protocol (MCP) server for LightRAG - Complete RAG and Knowledge Graph integration with 30+ tools",
5
5
  "keywords": [
6
6
  "mcp",