@danielsimonjr/memory-mcp 0.7.2 → 0.41.0
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/__tests__/edge-cases/edge-cases.test.js +406 -0
- package/dist/__tests__/file-path.test.js +5 -5
- package/dist/__tests__/integration/workflows.test.js +449 -0
- package/dist/__tests__/knowledge-graph.test.js +8 -3
- package/dist/__tests__/performance/benchmarks.test.js +411 -0
- package/dist/__tests__/unit/core/EntityManager.test.js +334 -0
- package/dist/__tests__/unit/core/GraphStorage.test.js +205 -0
- package/dist/__tests__/unit/core/RelationManager.test.js +274 -0
- package/dist/__tests__/unit/features/CompressionManager.test.js +350 -0
- package/dist/__tests__/unit/search/BasicSearch.test.js +311 -0
- package/dist/__tests__/unit/search/BooleanSearch.test.js +432 -0
- package/dist/__tests__/unit/search/FuzzySearch.test.js +448 -0
- package/dist/__tests__/unit/search/RankedSearch.test.js +379 -0
- package/dist/__tests__/unit/utils/levenshtein.test.js +77 -0
- package/dist/core/EntityManager.js +554 -0
- package/dist/core/GraphStorage.js +172 -0
- package/dist/core/KnowledgeGraphManager.js +400 -0
- package/dist/core/ObservationManager.js +129 -0
- package/dist/core/RelationManager.js +186 -0
- package/dist/core/TransactionManager.js +389 -0
- package/dist/core/index.js +9 -0
- package/dist/features/AnalyticsManager.js +222 -0
- package/dist/features/ArchiveManager.js +74 -0
- package/dist/features/BackupManager.js +311 -0
- package/dist/features/CompressionManager.js +310 -0
- package/dist/features/ExportManager.js +305 -0
- package/dist/features/HierarchyManager.js +219 -0
- package/dist/features/ImportExportManager.js +50 -0
- package/dist/features/ImportManager.js +328 -0
- package/dist/features/TagManager.js +210 -0
- package/dist/features/index.js +12 -0
- package/dist/index.js +13 -996
- package/dist/memory.jsonl +225 -0
- package/dist/search/BasicSearch.js +161 -0
- package/dist/search/BooleanSearch.js +304 -0
- package/dist/search/FuzzySearch.js +115 -0
- package/dist/search/RankedSearch.js +206 -0
- package/dist/search/SavedSearchManager.js +145 -0
- package/dist/search/SearchManager.js +305 -0
- package/dist/search/SearchSuggestions.js +57 -0
- package/dist/search/TFIDFIndexManager.js +217 -0
- package/dist/search/index.js +10 -0
- package/dist/server/MCPServer.js +889 -0
- package/dist/types/analytics.types.js +6 -0
- package/dist/types/entity.types.js +7 -0
- package/dist/types/import-export.types.js +7 -0
- package/dist/types/index.js +12 -0
- package/dist/types/search.types.js +7 -0
- package/dist/types/tag.types.js +6 -0
- package/dist/utils/constants.js +127 -0
- package/dist/utils/dateUtils.js +89 -0
- package/dist/utils/errors.js +121 -0
- package/dist/utils/index.js +13 -0
- package/dist/utils/levenshtein.js +62 -0
- package/dist/utils/logger.js +33 -0
- package/dist/utils/pathUtils.js +115 -0
- package/dist/utils/schemas.js +184 -0
- package/dist/utils/searchCache.js +209 -0
- package/dist/utils/tfidf.js +90 -0
- package/dist/utils/validationUtils.js +109 -0
- package/package.json +50 -48
|
@@ -0,0 +1,889 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Handles Model Context Protocol server initialization and tool registration.
|
|
5
|
+
*
|
|
6
|
+
* @module server/MCPServer
|
|
7
|
+
*/
|
|
8
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
9
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
10
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
11
|
+
import { logger } from '../utils/logger.js';
|
|
12
|
+
/**
|
|
13
|
+
* MCP Server for Knowledge Graph operations.
|
|
14
|
+
* Exposes tools for entity/relation management, search, and analysis.
|
|
15
|
+
*/
|
|
16
|
+
export class MCPServer {
|
|
17
|
+
server;
|
|
18
|
+
manager;
|
|
19
|
+
constructor(manager) {
|
|
20
|
+
this.manager = manager;
|
|
21
|
+
this.server = new Server({
|
|
22
|
+
name: "memory-server",
|
|
23
|
+
version: "0.8.0",
|
|
24
|
+
}, {
|
|
25
|
+
capabilities: {
|
|
26
|
+
tools: {},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
this.registerToolHandlers();
|
|
30
|
+
}
|
|
31
|
+
registerToolHandlers() {
|
|
32
|
+
// Register list tools handler
|
|
33
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
34
|
+
return {
|
|
35
|
+
tools: this.getToolDefinitions(),
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
// Register call tool handler
|
|
39
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
40
|
+
const { name, arguments: args } = request.params;
|
|
41
|
+
return this.handleToolCall(name, args || {});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
getToolDefinitions() {
|
|
45
|
+
return [
|
|
46
|
+
{
|
|
47
|
+
name: "create_entities",
|
|
48
|
+
description: "Create multiple new entities in the knowledge graph",
|
|
49
|
+
inputSchema: {
|
|
50
|
+
type: "object",
|
|
51
|
+
properties: {
|
|
52
|
+
entities: {
|
|
53
|
+
type: "array",
|
|
54
|
+
items: {
|
|
55
|
+
type: "object",
|
|
56
|
+
properties: {
|
|
57
|
+
name: { type: "string", description: "The name of the entity" },
|
|
58
|
+
entityType: { type: "string", description: "The type of the entity" },
|
|
59
|
+
observations: {
|
|
60
|
+
type: "array",
|
|
61
|
+
items: { type: "string" },
|
|
62
|
+
description: "An array of observation contents associated with the entity"
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
required: ["name", "entityType", "observations"],
|
|
66
|
+
additionalProperties: false,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
required: ["entities"],
|
|
71
|
+
additionalProperties: false,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: "create_relations",
|
|
76
|
+
description: "Create multiple new relations between entities in the knowledge graph. Relations should be in active voice",
|
|
77
|
+
inputSchema: {
|
|
78
|
+
type: "object",
|
|
79
|
+
properties: {
|
|
80
|
+
relations: {
|
|
81
|
+
type: "array",
|
|
82
|
+
items: {
|
|
83
|
+
type: "object",
|
|
84
|
+
properties: {
|
|
85
|
+
from: { type: "string", description: "The name of the entity where the relation starts" },
|
|
86
|
+
to: { type: "string", description: "The name of the entity where the relation ends" },
|
|
87
|
+
relationType: { type: "string", description: "The type of the relation in active voice (e.g., 'works_at', 'knows')" },
|
|
88
|
+
},
|
|
89
|
+
required: ["from", "to", "relationType"],
|
|
90
|
+
additionalProperties: false,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
required: ["relations"],
|
|
95
|
+
additionalProperties: false,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: "add_observations",
|
|
100
|
+
description: "Add new observations to existing entities in the knowledge graph",
|
|
101
|
+
inputSchema: {
|
|
102
|
+
type: "object",
|
|
103
|
+
properties: {
|
|
104
|
+
observations: {
|
|
105
|
+
type: "array",
|
|
106
|
+
items: {
|
|
107
|
+
type: "object",
|
|
108
|
+
properties: {
|
|
109
|
+
entityName: { type: "string", description: "The name of the entity to add observations to" },
|
|
110
|
+
contents: {
|
|
111
|
+
type: "array",
|
|
112
|
+
items: { type: "string" },
|
|
113
|
+
description: "An array of observation contents to add"
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
required: ["entityName", "contents"],
|
|
117
|
+
additionalProperties: false,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
required: ["observations"],
|
|
122
|
+
additionalProperties: false,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "delete_entities",
|
|
127
|
+
description: "Delete multiple entities from the knowledge graph",
|
|
128
|
+
inputSchema: {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {
|
|
131
|
+
entityNames: {
|
|
132
|
+
type: "array",
|
|
133
|
+
items: { type: "string" },
|
|
134
|
+
description: "An array of entity names to delete"
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
required: ["entityNames"],
|
|
138
|
+
additionalProperties: false,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "delete_observations",
|
|
143
|
+
description: "Delete specific observations from entities",
|
|
144
|
+
inputSchema: {
|
|
145
|
+
type: "object",
|
|
146
|
+
properties: {
|
|
147
|
+
deletions: {
|
|
148
|
+
type: "array",
|
|
149
|
+
items: {
|
|
150
|
+
type: "object",
|
|
151
|
+
properties: {
|
|
152
|
+
entityName: { type: "string" },
|
|
153
|
+
observations: {
|
|
154
|
+
type: "array",
|
|
155
|
+
items: { type: "string" }
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
required: ["entityName", "observations"],
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
required: ["deletions"],
|
|
163
|
+
additionalProperties: false,
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: "delete_relations",
|
|
168
|
+
description: "Delete multiple relations from the knowledge graph",
|
|
169
|
+
inputSchema: {
|
|
170
|
+
type: "object",
|
|
171
|
+
properties: {
|
|
172
|
+
relations: {
|
|
173
|
+
type: "array",
|
|
174
|
+
items: {
|
|
175
|
+
type: "object",
|
|
176
|
+
properties: {
|
|
177
|
+
from: { type: "string" },
|
|
178
|
+
to: { type: "string" },
|
|
179
|
+
relationType: { type: "string" },
|
|
180
|
+
},
|
|
181
|
+
required: ["from", "to", "relationType"],
|
|
182
|
+
additionalProperties: false,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
required: ["relations"],
|
|
187
|
+
additionalProperties: false,
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: "read_graph",
|
|
192
|
+
description: "Read the entire knowledge graph",
|
|
193
|
+
inputSchema: {
|
|
194
|
+
type: "object",
|
|
195
|
+
properties: {},
|
|
196
|
+
additionalProperties: false,
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
name: "search_nodes",
|
|
201
|
+
description: "Search for nodes in the knowledge graph based on query string, with optional tag and importance filtering",
|
|
202
|
+
inputSchema: {
|
|
203
|
+
type: "object",
|
|
204
|
+
properties: {
|
|
205
|
+
query: { type: "string", description: "The search query" },
|
|
206
|
+
tags: {
|
|
207
|
+
type: "array",
|
|
208
|
+
items: { type: "string" },
|
|
209
|
+
description: "Optional array of tags to filter by"
|
|
210
|
+
},
|
|
211
|
+
minImportance: { type: "number", description: "Optional minimum importance score (0-10)" },
|
|
212
|
+
maxImportance: { type: "number", description: "Optional maximum importance score (0-10)" },
|
|
213
|
+
},
|
|
214
|
+
required: ["query"],
|
|
215
|
+
additionalProperties: false,
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: "open_nodes",
|
|
220
|
+
description: "Open specific nodes by their names",
|
|
221
|
+
inputSchema: {
|
|
222
|
+
type: "object",
|
|
223
|
+
properties: {
|
|
224
|
+
names: {
|
|
225
|
+
type: "array",
|
|
226
|
+
items: { type: "string" },
|
|
227
|
+
description: "Array of entity names to retrieve"
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
required: ["names"],
|
|
231
|
+
additionalProperties: false,
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: "search_by_date_range",
|
|
236
|
+
description: "Search entities within a date range, with optional filtering by entity type and tags",
|
|
237
|
+
inputSchema: {
|
|
238
|
+
type: "object",
|
|
239
|
+
properties: {
|
|
240
|
+
startDate: { type: "string", description: "Start date in ISO 8601 format" },
|
|
241
|
+
endDate: { type: "string", description: "End date in ISO 8601 format" },
|
|
242
|
+
entityType: { type: "string", description: "Optional entity type to filter by" },
|
|
243
|
+
tags: {
|
|
244
|
+
type: "array",
|
|
245
|
+
items: { type: "string" },
|
|
246
|
+
description: "Optional array of tags to filter by"
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
additionalProperties: false,
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: "add_tags",
|
|
254
|
+
description: "Add tags to an entity",
|
|
255
|
+
inputSchema: {
|
|
256
|
+
type: "object",
|
|
257
|
+
properties: {
|
|
258
|
+
entityName: { type: "string", description: "Name of the entity" },
|
|
259
|
+
tags: {
|
|
260
|
+
type: "array",
|
|
261
|
+
items: { type: "string" },
|
|
262
|
+
description: "Array of tags to add"
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
required: ["entityName", "tags"],
|
|
266
|
+
additionalProperties: false,
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
name: "remove_tags",
|
|
271
|
+
description: "Remove tags from an entity",
|
|
272
|
+
inputSchema: {
|
|
273
|
+
type: "object",
|
|
274
|
+
properties: {
|
|
275
|
+
entityName: { type: "string", description: "Name of the entity" },
|
|
276
|
+
tags: {
|
|
277
|
+
type: "array",
|
|
278
|
+
items: { type: "string" },
|
|
279
|
+
description: "Array of tags to remove"
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
required: ["entityName", "tags"],
|
|
283
|
+
additionalProperties: false,
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: "set_importance",
|
|
288
|
+
description: "Set the importance score of an entity (0-10)",
|
|
289
|
+
inputSchema: {
|
|
290
|
+
type: "object",
|
|
291
|
+
properties: {
|
|
292
|
+
entityName: { type: "string", description: "Name of the entity" },
|
|
293
|
+
importance: { type: "number", description: "Importance score between 0 and 10" },
|
|
294
|
+
},
|
|
295
|
+
required: ["entityName", "importance"],
|
|
296
|
+
additionalProperties: false,
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
name: "add_tags_to_multiple_entities",
|
|
301
|
+
description: "Add the same tags to multiple entities at once",
|
|
302
|
+
inputSchema: {
|
|
303
|
+
type: "object",
|
|
304
|
+
properties: {
|
|
305
|
+
entityNames: {
|
|
306
|
+
type: "array",
|
|
307
|
+
items: { type: "string" },
|
|
308
|
+
description: "Array of entity names"
|
|
309
|
+
},
|
|
310
|
+
tags: {
|
|
311
|
+
type: "array",
|
|
312
|
+
items: { type: "string" },
|
|
313
|
+
description: "Array of tags to add to all entities"
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
required: ["entityNames", "tags"],
|
|
317
|
+
additionalProperties: false,
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: "replace_tag",
|
|
322
|
+
description: "Replace a tag with a new tag across all entities",
|
|
323
|
+
inputSchema: {
|
|
324
|
+
type: "object",
|
|
325
|
+
properties: {
|
|
326
|
+
oldTag: { type: "string", description: "The tag to replace" },
|
|
327
|
+
newTag: { type: "string", description: "The new tag" },
|
|
328
|
+
},
|
|
329
|
+
required: ["oldTag", "newTag"],
|
|
330
|
+
additionalProperties: false,
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
name: "merge_tags",
|
|
335
|
+
description: "Merge two tags into a target tag across all entities",
|
|
336
|
+
inputSchema: {
|
|
337
|
+
type: "object",
|
|
338
|
+
properties: {
|
|
339
|
+
tag1: { type: "string", description: "First tag to merge" },
|
|
340
|
+
tag2: { type: "string", description: "Second tag to merge" },
|
|
341
|
+
targetTag: { type: "string", description: "Target tag to merge into" },
|
|
342
|
+
},
|
|
343
|
+
required: ["tag1", "tag2", "targetTag"],
|
|
344
|
+
additionalProperties: false,
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
name: "get_graph_stats",
|
|
349
|
+
description: "Get statistics about the knowledge graph",
|
|
350
|
+
inputSchema: {
|
|
351
|
+
type: "object",
|
|
352
|
+
properties: {},
|
|
353
|
+
additionalProperties: false,
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
name: "validate_graph",
|
|
358
|
+
description: "Validate the knowledge graph for integrity issues",
|
|
359
|
+
inputSchema: {
|
|
360
|
+
type: "object",
|
|
361
|
+
properties: {},
|
|
362
|
+
additionalProperties: false,
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
name: "save_search",
|
|
367
|
+
description: "Save a search query for later reuse",
|
|
368
|
+
inputSchema: {
|
|
369
|
+
type: "object",
|
|
370
|
+
properties: {
|
|
371
|
+
name: { type: "string", description: "Name of the saved search" },
|
|
372
|
+
query: { type: "string", description: "Search query" },
|
|
373
|
+
tags: {
|
|
374
|
+
type: "array",
|
|
375
|
+
items: { type: "string" },
|
|
376
|
+
description: "Optional tags filter"
|
|
377
|
+
},
|
|
378
|
+
minImportance: { type: "number", description: "Optional minimum importance" },
|
|
379
|
+
maxImportance: { type: "number", description: "Optional maximum importance" },
|
|
380
|
+
searchType: { type: "string", description: "Type of search (basic, boolean, fuzzy, ranked)" },
|
|
381
|
+
description: { type: "string", description: "Optional description of the search" },
|
|
382
|
+
},
|
|
383
|
+
required: ["name", "query"],
|
|
384
|
+
additionalProperties: false,
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
name: "execute_saved_search",
|
|
389
|
+
description: "Execute a previously saved search by name",
|
|
390
|
+
inputSchema: {
|
|
391
|
+
type: "object",
|
|
392
|
+
properties: {
|
|
393
|
+
name: { type: "string", description: "Name of the saved search" },
|
|
394
|
+
},
|
|
395
|
+
required: ["name"],
|
|
396
|
+
additionalProperties: false,
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
name: "list_saved_searches",
|
|
401
|
+
description: "List all saved searches",
|
|
402
|
+
inputSchema: {
|
|
403
|
+
type: "object",
|
|
404
|
+
properties: {},
|
|
405
|
+
additionalProperties: false,
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
name: "delete_saved_search",
|
|
410
|
+
description: "Delete a saved search",
|
|
411
|
+
inputSchema: {
|
|
412
|
+
type: "object",
|
|
413
|
+
properties: {
|
|
414
|
+
name: { type: "string", description: "Name of the saved search to delete" },
|
|
415
|
+
},
|
|
416
|
+
required: ["name"],
|
|
417
|
+
additionalProperties: false,
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
name: "update_saved_search",
|
|
422
|
+
description: "Update a saved search",
|
|
423
|
+
inputSchema: {
|
|
424
|
+
type: "object",
|
|
425
|
+
properties: {
|
|
426
|
+
name: { type: "string", description: "Name of the saved search" },
|
|
427
|
+
updates: {
|
|
428
|
+
type: "object",
|
|
429
|
+
description: "Fields to update",
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
required: ["name", "updates"],
|
|
433
|
+
additionalProperties: false,
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
name: "boolean_search",
|
|
438
|
+
description: "Perform boolean search with AND, OR, NOT operators",
|
|
439
|
+
inputSchema: {
|
|
440
|
+
type: "object",
|
|
441
|
+
properties: {
|
|
442
|
+
query: { type: "string", description: "Boolean query (e.g., 'alice AND bob')" },
|
|
443
|
+
tags: {
|
|
444
|
+
type: "array",
|
|
445
|
+
items: { type: "string" },
|
|
446
|
+
},
|
|
447
|
+
minImportance: { type: "number" },
|
|
448
|
+
maxImportance: { type: "number" },
|
|
449
|
+
},
|
|
450
|
+
required: ["query"],
|
|
451
|
+
additionalProperties: false,
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
name: "fuzzy_search",
|
|
456
|
+
description: "Perform fuzzy search with typo tolerance",
|
|
457
|
+
inputSchema: {
|
|
458
|
+
type: "object",
|
|
459
|
+
properties: {
|
|
460
|
+
query: { type: "string", description: "Search query" },
|
|
461
|
+
threshold: { type: "number", description: "Similarity threshold (0.0-1.0)" },
|
|
462
|
+
tags: {
|
|
463
|
+
type: "array",
|
|
464
|
+
items: { type: "string" },
|
|
465
|
+
},
|
|
466
|
+
minImportance: { type: "number" },
|
|
467
|
+
maxImportance: { type: "number" },
|
|
468
|
+
},
|
|
469
|
+
required: ["query"],
|
|
470
|
+
additionalProperties: false,
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
name: "search_nodes_ranked",
|
|
475
|
+
description: "Perform TF-IDF ranked search",
|
|
476
|
+
inputSchema: {
|
|
477
|
+
type: "object",
|
|
478
|
+
properties: {
|
|
479
|
+
query: { type: "string", description: "Search query" },
|
|
480
|
+
tags: {
|
|
481
|
+
type: "array",
|
|
482
|
+
items: { type: "string" },
|
|
483
|
+
},
|
|
484
|
+
minImportance: { type: "number" },
|
|
485
|
+
maxImportance: { type: "number" },
|
|
486
|
+
limit: { type: "number", description: "Max results" },
|
|
487
|
+
},
|
|
488
|
+
required: ["query"],
|
|
489
|
+
additionalProperties: false,
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
name: "get_search_suggestions",
|
|
494
|
+
description: "Get search suggestions for a query",
|
|
495
|
+
inputSchema: {
|
|
496
|
+
type: "object",
|
|
497
|
+
properties: {
|
|
498
|
+
query: { type: "string", description: "Search query" },
|
|
499
|
+
maxSuggestions: { type: "number", description: "Max suggestions to return" },
|
|
500
|
+
},
|
|
501
|
+
required: ["query"],
|
|
502
|
+
additionalProperties: false,
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
name: "add_tag_alias",
|
|
507
|
+
description: "Add a tag alias (synonym mapping)",
|
|
508
|
+
inputSchema: {
|
|
509
|
+
type: "object",
|
|
510
|
+
properties: {
|
|
511
|
+
alias: { type: "string", description: "The alias/synonym" },
|
|
512
|
+
canonical: { type: "string", description: "The canonical tag" },
|
|
513
|
+
description: { type: "string", description: "Optional description" },
|
|
514
|
+
},
|
|
515
|
+
required: ["alias", "canonical"],
|
|
516
|
+
additionalProperties: false,
|
|
517
|
+
},
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
name: "list_tag_aliases",
|
|
521
|
+
description: "List all tag aliases",
|
|
522
|
+
inputSchema: {
|
|
523
|
+
type: "object",
|
|
524
|
+
properties: {},
|
|
525
|
+
additionalProperties: false,
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
name: "remove_tag_alias",
|
|
530
|
+
description: "Remove a tag alias",
|
|
531
|
+
inputSchema: {
|
|
532
|
+
type: "object",
|
|
533
|
+
properties: {
|
|
534
|
+
alias: { type: "string", description: "The alias to remove" },
|
|
535
|
+
},
|
|
536
|
+
required: ["alias"],
|
|
537
|
+
additionalProperties: false,
|
|
538
|
+
},
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
name: "get_aliases_for_tag",
|
|
542
|
+
description: "Get all aliases for a canonical tag",
|
|
543
|
+
inputSchema: {
|
|
544
|
+
type: "object",
|
|
545
|
+
properties: {
|
|
546
|
+
canonicalTag: { type: "string", description: "The canonical tag" },
|
|
547
|
+
},
|
|
548
|
+
required: ["canonicalTag"],
|
|
549
|
+
additionalProperties: false,
|
|
550
|
+
},
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
name: "resolve_tag",
|
|
554
|
+
description: "Resolve a tag to its canonical form",
|
|
555
|
+
inputSchema: {
|
|
556
|
+
type: "object",
|
|
557
|
+
properties: {
|
|
558
|
+
tag: { type: "string", description: "Tag to resolve" },
|
|
559
|
+
},
|
|
560
|
+
required: ["tag"],
|
|
561
|
+
additionalProperties: false,
|
|
562
|
+
},
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
name: "set_entity_parent",
|
|
566
|
+
description: "Set the parent of an entity for hierarchical organization",
|
|
567
|
+
inputSchema: {
|
|
568
|
+
type: "object",
|
|
569
|
+
properties: {
|
|
570
|
+
entityName: { type: "string" },
|
|
571
|
+
parentName: { type: ["string", "null"], description: "Parent entity name or null to remove parent" },
|
|
572
|
+
},
|
|
573
|
+
required: ["entityName", "parentName"],
|
|
574
|
+
additionalProperties: false,
|
|
575
|
+
},
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
name: "get_children",
|
|
579
|
+
description: "Get all child entities of an entity",
|
|
580
|
+
inputSchema: {
|
|
581
|
+
type: "object",
|
|
582
|
+
properties: {
|
|
583
|
+
entityName: { type: "string" },
|
|
584
|
+
},
|
|
585
|
+
required: ["entityName"],
|
|
586
|
+
additionalProperties: false,
|
|
587
|
+
},
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
name: "get_parent",
|
|
591
|
+
description: "Get the parent entity of an entity",
|
|
592
|
+
inputSchema: {
|
|
593
|
+
type: "object",
|
|
594
|
+
properties: {
|
|
595
|
+
entityName: { type: "string" },
|
|
596
|
+
},
|
|
597
|
+
required: ["entityName"],
|
|
598
|
+
additionalProperties: false,
|
|
599
|
+
},
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
name: "get_ancestors",
|
|
603
|
+
description: "Get all ancestor entities of an entity",
|
|
604
|
+
inputSchema: {
|
|
605
|
+
type: "object",
|
|
606
|
+
properties: {
|
|
607
|
+
entityName: { type: "string" },
|
|
608
|
+
},
|
|
609
|
+
required: ["entityName"],
|
|
610
|
+
additionalProperties: false,
|
|
611
|
+
},
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
name: "get_descendants",
|
|
615
|
+
description: "Get all descendant entities of an entity",
|
|
616
|
+
inputSchema: {
|
|
617
|
+
type: "object",
|
|
618
|
+
properties: {
|
|
619
|
+
entityName: { type: "string" },
|
|
620
|
+
},
|
|
621
|
+
required: ["entityName"],
|
|
622
|
+
additionalProperties: false,
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
name: "get_subtree",
|
|
627
|
+
description: "Get entity and all its descendants as a subgraph",
|
|
628
|
+
inputSchema: {
|
|
629
|
+
type: "object",
|
|
630
|
+
properties: {
|
|
631
|
+
entityName: { type: "string" },
|
|
632
|
+
},
|
|
633
|
+
required: ["entityName"],
|
|
634
|
+
additionalProperties: false,
|
|
635
|
+
},
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
name: "get_root_entities",
|
|
639
|
+
description: "Get all root entities (entities without parents)",
|
|
640
|
+
inputSchema: {
|
|
641
|
+
type: "object",
|
|
642
|
+
properties: {},
|
|
643
|
+
additionalProperties: false,
|
|
644
|
+
},
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
name: "get_entity_depth",
|
|
648
|
+
description: "Get the depth of an entity in the hierarchy",
|
|
649
|
+
inputSchema: {
|
|
650
|
+
type: "object",
|
|
651
|
+
properties: {
|
|
652
|
+
entityName: { type: "string" },
|
|
653
|
+
},
|
|
654
|
+
required: ["entityName"],
|
|
655
|
+
additionalProperties: false,
|
|
656
|
+
},
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
name: "move_entity",
|
|
660
|
+
description: "Move an entity to a new parent",
|
|
661
|
+
inputSchema: {
|
|
662
|
+
type: "object",
|
|
663
|
+
properties: {
|
|
664
|
+
entityName: { type: "string" },
|
|
665
|
+
newParentName: { type: ["string", "null"] },
|
|
666
|
+
},
|
|
667
|
+
required: ["entityName", "newParentName"],
|
|
668
|
+
additionalProperties: false,
|
|
669
|
+
},
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
name: "find_duplicates",
|
|
673
|
+
description: "Find potential duplicate entities based on similarity",
|
|
674
|
+
inputSchema: {
|
|
675
|
+
type: "object",
|
|
676
|
+
properties: {
|
|
677
|
+
threshold: { type: "number", description: "Similarity threshold (0.0-1.0)" },
|
|
678
|
+
},
|
|
679
|
+
additionalProperties: false,
|
|
680
|
+
},
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
name: "merge_entities",
|
|
684
|
+
description: "Merge multiple entities into one",
|
|
685
|
+
inputSchema: {
|
|
686
|
+
type: "object",
|
|
687
|
+
properties: {
|
|
688
|
+
entityNames: {
|
|
689
|
+
type: "array",
|
|
690
|
+
items: { type: "string" },
|
|
691
|
+
description: "Entities to merge"
|
|
692
|
+
},
|
|
693
|
+
targetName: { type: "string", description: "Optional target entity name" },
|
|
694
|
+
},
|
|
695
|
+
required: ["entityNames"],
|
|
696
|
+
additionalProperties: false,
|
|
697
|
+
},
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
name: "compress_graph",
|
|
701
|
+
description: "Compress the graph by merging similar entities",
|
|
702
|
+
inputSchema: {
|
|
703
|
+
type: "object",
|
|
704
|
+
properties: {
|
|
705
|
+
threshold: { type: "number", description: "Similarity threshold" },
|
|
706
|
+
dryRun: { type: "boolean", description: "Preview without applying changes" },
|
|
707
|
+
},
|
|
708
|
+
additionalProperties: false,
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
name: "archive_entities",
|
|
713
|
+
description: "Archive old or low-importance entities",
|
|
714
|
+
inputSchema: {
|
|
715
|
+
type: "object",
|
|
716
|
+
properties: {
|
|
717
|
+
olderThan: { type: "string", description: "Archive entities older than this date (ISO 8601)" },
|
|
718
|
+
importanceLessThan: { type: "number", description: "Archive entities below this importance" },
|
|
719
|
+
tags: {
|
|
720
|
+
type: "array",
|
|
721
|
+
items: { type: "string" },
|
|
722
|
+
description: "Archive entities with these tags"
|
|
723
|
+
},
|
|
724
|
+
dryRun: { type: "boolean", description: "Preview without applying changes" },
|
|
725
|
+
},
|
|
726
|
+
additionalProperties: false,
|
|
727
|
+
},
|
|
728
|
+
},
|
|
729
|
+
{
|
|
730
|
+
name: "import_graph",
|
|
731
|
+
description: "Import knowledge graph from various formats",
|
|
732
|
+
inputSchema: {
|
|
733
|
+
type: "object",
|
|
734
|
+
properties: {
|
|
735
|
+
format: { type: "string", enum: ["json", "csv", "graphml"] },
|
|
736
|
+
data: { type: "string", description: "Import data as string" },
|
|
737
|
+
mergeStrategy: {
|
|
738
|
+
type: "string",
|
|
739
|
+
enum: ["replace", "skip", "merge", "fail"],
|
|
740
|
+
description: "How to handle conflicts"
|
|
741
|
+
},
|
|
742
|
+
dryRun: { type: "boolean", description: "Preview without applying changes" },
|
|
743
|
+
},
|
|
744
|
+
required: ["format", "data"],
|
|
745
|
+
additionalProperties: false,
|
|
746
|
+
},
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
name: "export_graph",
|
|
750
|
+
description: "Export knowledge graph in various formats",
|
|
751
|
+
inputSchema: {
|
|
752
|
+
type: "object",
|
|
753
|
+
properties: {
|
|
754
|
+
format: {
|
|
755
|
+
type: "string",
|
|
756
|
+
enum: ["json", "csv", "graphml", "gexf", "dot", "markdown", "mermaid"],
|
|
757
|
+
description: "Export format"
|
|
758
|
+
},
|
|
759
|
+
filter: {
|
|
760
|
+
type: "object",
|
|
761
|
+
properties: {
|
|
762
|
+
startDate: { type: "string" },
|
|
763
|
+
endDate: { type: "string" },
|
|
764
|
+
entityType: { type: "string" },
|
|
765
|
+
tags: {
|
|
766
|
+
type: "array",
|
|
767
|
+
items: { type: "string" }
|
|
768
|
+
},
|
|
769
|
+
},
|
|
770
|
+
description: "Optional filter"
|
|
771
|
+
},
|
|
772
|
+
},
|
|
773
|
+
required: ["format"],
|
|
774
|
+
additionalProperties: false,
|
|
775
|
+
},
|
|
776
|
+
},
|
|
777
|
+
];
|
|
778
|
+
}
|
|
779
|
+
async handleToolCall(name, args) {
|
|
780
|
+
switch (name) {
|
|
781
|
+
case "create_entities":
|
|
782
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.createEntities(args.entities), null, 2) }] };
|
|
783
|
+
case "create_relations":
|
|
784
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.createRelations(args.relations), null, 2) }] };
|
|
785
|
+
case "add_observations":
|
|
786
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.addObservations(args.observations), null, 2) }] };
|
|
787
|
+
case "delete_entities":
|
|
788
|
+
await this.manager.deleteEntities(args.entityNames);
|
|
789
|
+
return { content: [{ type: "text", text: `Deleted ${args.entityNames.length} entities` }] };
|
|
790
|
+
case "delete_observations":
|
|
791
|
+
await this.manager.deleteObservations(args.deletions);
|
|
792
|
+
return { content: [{ type: "text", text: "Observations deleted successfully" }] };
|
|
793
|
+
case "delete_relations":
|
|
794
|
+
await this.manager.deleteRelations(args.relations);
|
|
795
|
+
return { content: [{ type: "text", text: `Deleted ${args.relations.length} relations` }] };
|
|
796
|
+
case "read_graph":
|
|
797
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.readGraph(), null, 2) }] };
|
|
798
|
+
case "search_nodes":
|
|
799
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.searchNodes(args.query, args.tags, args.minImportance, args.maxImportance), null, 2) }] };
|
|
800
|
+
case "open_nodes":
|
|
801
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.openNodes(args.names), null, 2) }] };
|
|
802
|
+
case "search_nodes_ranked":
|
|
803
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.searchNodesRanked(args.query, args.tags, args.minImportance, args.maxImportance, args.limit), null, 2) }] };
|
|
804
|
+
case "list_saved_searches":
|
|
805
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.listSavedSearches(), null, 2) }] };
|
|
806
|
+
case "search_by_date_range":
|
|
807
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.searchByDateRange(args.startDate, args.endDate, args.entityType, args.tags), null, 2) }] };
|
|
808
|
+
case "add_tags":
|
|
809
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.addTags(args.entityName, args.tags), null, 2) }] };
|
|
810
|
+
case "remove_tags":
|
|
811
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.removeTags(args.entityName, args.tags), null, 2) }] };
|
|
812
|
+
case "set_importance":
|
|
813
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.setImportance(args.entityName, args.importance), null, 2) }] };
|
|
814
|
+
case "add_tags_to_multiple_entities":
|
|
815
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.addTagsToMultipleEntities(args.entityNames, args.tags), null, 2) }] };
|
|
816
|
+
case "replace_tag":
|
|
817
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.replaceTag(args.oldTag, args.newTag), null, 2) }] };
|
|
818
|
+
case "merge_tags":
|
|
819
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.mergeTags(args.tag1, args.tag2, args.targetTag), null, 2) }] };
|
|
820
|
+
case "save_search":
|
|
821
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.saveSearch(args), null, 2) }] };
|
|
822
|
+
case "execute_saved_search":
|
|
823
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.executeSavedSearch(args.name), null, 2) }] };
|
|
824
|
+
case "delete_saved_search":
|
|
825
|
+
const deleted = await this.manager.deleteSavedSearch(args.name);
|
|
826
|
+
return { content: [{ type: "text", text: deleted ? `Saved search "${args.name}" deleted successfully` : `Saved search "${args.name}" not found` }] };
|
|
827
|
+
case "update_saved_search":
|
|
828
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.updateSavedSearch(args.name, args.updates), null, 2) }] };
|
|
829
|
+
case "boolean_search":
|
|
830
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.booleanSearch(args.query, args.tags, args.minImportance, args.maxImportance), null, 2) }] };
|
|
831
|
+
case "fuzzy_search":
|
|
832
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.fuzzySearch(args.query, args.threshold, args.tags, args.minImportance, args.maxImportance), null, 2) }] };
|
|
833
|
+
case "get_search_suggestions":
|
|
834
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.getSearchSuggestions(args.query, args.maxSuggestions), null, 2) }] };
|
|
835
|
+
case "add_tag_alias":
|
|
836
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.addTagAlias(args.alias, args.canonical, args.description), null, 2) }] };
|
|
837
|
+
case "list_tag_aliases":
|
|
838
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.listTagAliases(), null, 2) }] };
|
|
839
|
+
case "remove_tag_alias":
|
|
840
|
+
const removed = await this.manager.removeTagAlias(args.alias);
|
|
841
|
+
return { content: [{ type: "text", text: removed ? `Tag alias "${args.alias}" removed successfully` : `Tag alias "${args.alias}" not found` }] };
|
|
842
|
+
case "get_aliases_for_tag":
|
|
843
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.getAliasesForTag(args.canonicalTag), null, 2) }] };
|
|
844
|
+
case "resolve_tag":
|
|
845
|
+
return { content: [{ type: "text", text: JSON.stringify({ tag: args.tag, resolved: await this.manager.resolveTag(args.tag) }, null, 2) }] };
|
|
846
|
+
case "set_entity_parent":
|
|
847
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.setEntityParent(args.entityName, args.parentName), null, 2) }] };
|
|
848
|
+
case "get_children":
|
|
849
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.getChildren(args.entityName), null, 2) }] };
|
|
850
|
+
case "get_parent":
|
|
851
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.getParent(args.entityName), null, 2) }] };
|
|
852
|
+
case "get_ancestors":
|
|
853
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.getAncestors(args.entityName), null, 2) }] };
|
|
854
|
+
case "get_descendants":
|
|
855
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.getDescendants(args.entityName), null, 2) }] };
|
|
856
|
+
case "get_subtree":
|
|
857
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.getSubtree(args.entityName), null, 2) }] };
|
|
858
|
+
case "get_root_entities":
|
|
859
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.getRootEntities(), null, 2) }] };
|
|
860
|
+
case "get_entity_depth":
|
|
861
|
+
return { content: [{ type: "text", text: JSON.stringify({ entityName: args.entityName, depth: await this.manager.getEntityDepth(args.entityName) }, null, 2) }] };
|
|
862
|
+
case "move_entity":
|
|
863
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.moveEntity(args.entityName, args.newParentName), null, 2) }] };
|
|
864
|
+
case "get_graph_stats":
|
|
865
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.getGraphStats(), null, 2) }] };
|
|
866
|
+
case "validate_graph":
|
|
867
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.validateGraph(), null, 2) }] };
|
|
868
|
+
case "find_duplicates":
|
|
869
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.findDuplicates(args.threshold), null, 2) }] };
|
|
870
|
+
case "merge_entities":
|
|
871
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.mergeEntities(args.entityNames, args.targetName), null, 2) }] };
|
|
872
|
+
case "compress_graph":
|
|
873
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.compressGraph(args.threshold, args.dryRun), null, 2) }] };
|
|
874
|
+
case "archive_entities":
|
|
875
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.archiveEntities({ olderThan: args.olderThan, importanceLessThan: args.importanceLessThan, tags: args.tags }, args.dryRun), null, 2) }] };
|
|
876
|
+
case "import_graph":
|
|
877
|
+
return { content: [{ type: "text", text: JSON.stringify(await this.manager.importGraph(args.format, args.data, args.mergeStrategy, args.dryRun), null, 2) }] };
|
|
878
|
+
case "export_graph":
|
|
879
|
+
return { content: [{ type: "text", text: await this.manager.exportGraph(args.format, args.filter) }] };
|
|
880
|
+
default:
|
|
881
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
async start() {
|
|
885
|
+
const transport = new StdioServerTransport();
|
|
886
|
+
await this.server.connect(transport);
|
|
887
|
+
logger.info('Knowledge Graph MCP Server running on stdio');
|
|
888
|
+
}
|
|
889
|
+
}
|