@grafema/mcp 0.3.28 → 0.3.29
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/definitions/enox-tools.d.ts +10 -0
- package/dist/definitions/enox-tools.d.ts.map +1 -0
- package/dist/definitions/enox-tools.js +456 -0
- package/dist/definitions/enox-tools.js.map +1 -0
- package/dist/definitions/index.js +2 -2
- package/dist/definitions/index.js.map +1 -1
- package/dist/handlers/enox-handlers.d.ts +104 -0
- package/dist/handlers/enox-handlers.d.ts.map +1 -0
- package/dist/handlers/enox-handlers.js +869 -0
- package/dist/handlers/enox-handlers.js.map +1 -0
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.d.ts.map +1 -1
- package/dist/handlers/index.js +1 -1
- package/dist/handlers/index.js.map +1 -1
- package/dist/server.js +45 -17
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +64 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/definitions/enox-tools.ts +459 -0
- package/src/definitions/index.ts +2 -2
- package/src/handlers/enox-handlers.ts +1114 -0
- package/src/handlers/index.ts +1 -1
- package/src/server.ts +86 -29
- package/src/types.ts +78 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enox Tools — persistent knowledge graph (long-term memory)
|
|
3
|
+
*
|
|
4
|
+
* Enox is a federated knowledge graph shared across sessions and projects.
|
|
5
|
+
* These tools provide CRUD operations on nodes and edges, semantic search,
|
|
6
|
+
* graph traversal, and document storage.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ToolDefinition } from './types.js';
|
|
10
|
+
|
|
11
|
+
const RELATION_TYPES = [
|
|
12
|
+
'depends_on',
|
|
13
|
+
'supersedes',
|
|
14
|
+
'implements',
|
|
15
|
+
'contradicts',
|
|
16
|
+
'part_of',
|
|
17
|
+
'extends',
|
|
18
|
+
'enables',
|
|
19
|
+
'isomorphic_to',
|
|
20
|
+
'decided_on',
|
|
21
|
+
'discussed_on',
|
|
22
|
+
'changed_on',
|
|
23
|
+
'created_on',
|
|
24
|
+
'preceded_by',
|
|
25
|
+
'triggered_by',
|
|
26
|
+
'prefers',
|
|
27
|
+
'distrusts',
|
|
28
|
+
'values',
|
|
29
|
+
'rejects',
|
|
30
|
+
'believes',
|
|
31
|
+
'about',
|
|
32
|
+
'references',
|
|
33
|
+
'blocks',
|
|
34
|
+
'decomposes_into',
|
|
35
|
+
'related_to',
|
|
36
|
+
'similar_to',
|
|
37
|
+
'requires',
|
|
38
|
+
'supports',
|
|
39
|
+
'outperforms',
|
|
40
|
+
'fails_on',
|
|
41
|
+
'introduces',
|
|
42
|
+
'uses',
|
|
43
|
+
'is_based_on',
|
|
44
|
+
'equivalent_to',
|
|
45
|
+
'foundational_for',
|
|
46
|
+
'builds_on',
|
|
47
|
+
'contributes_to',
|
|
48
|
+
'alternative_to',
|
|
49
|
+
'refutes',
|
|
50
|
+
'challenges',
|
|
51
|
+
'applies_to',
|
|
52
|
+
'exports',
|
|
53
|
+
] as const;
|
|
54
|
+
|
|
55
|
+
export const ENOX_TOOLS: ToolDefinition[] = [
|
|
56
|
+
{
|
|
57
|
+
name: 'remember',
|
|
58
|
+
description: `Quick knowledge write — store a fact about a subject.
|
|
59
|
+
|
|
60
|
+
Use this when you:
|
|
61
|
+
- Discover something worth remembering across sessions
|
|
62
|
+
- Want to record an experiment result, decision, or observation
|
|
63
|
+
- Need a quick "jot it down" without specifying exact graph structure
|
|
64
|
+
|
|
65
|
+
The subject becomes a node (or reuses an existing one), and the fact is stored
|
|
66
|
+
as an assertion from that node.
|
|
67
|
+
|
|
68
|
+
Example: remember(subject="RFDB compaction", fact="flush_data_only was a no-op in V2 engine", domain="engineering")`,
|
|
69
|
+
inputSchema: {
|
|
70
|
+
type: 'object',
|
|
71
|
+
properties: {
|
|
72
|
+
subject: {
|
|
73
|
+
type: 'string',
|
|
74
|
+
description: 'The entity this fact is about (becomes a node)',
|
|
75
|
+
},
|
|
76
|
+
fact: {
|
|
77
|
+
type: 'string',
|
|
78
|
+
description: 'The fact or observation to record',
|
|
79
|
+
},
|
|
80
|
+
domain: {
|
|
81
|
+
type: 'string',
|
|
82
|
+
description: 'Knowledge domain (default: "memory")',
|
|
83
|
+
},
|
|
84
|
+
confidence: {
|
|
85
|
+
type: 'number',
|
|
86
|
+
description: 'Confidence level 0-1 (default: 0.9)',
|
|
87
|
+
},
|
|
88
|
+
relation: {
|
|
89
|
+
type: 'string',
|
|
90
|
+
description: 'Relation type for the assertion edge',
|
|
91
|
+
enum: [...RELATION_TYPES],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
required: ['subject', 'fact'],
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'recall',
|
|
99
|
+
description: `Broad "what do we know about X" — combines embedding search with graph traversal.
|
|
100
|
+
|
|
101
|
+
Use this at session start or before making decisions to check for prior art,
|
|
102
|
+
known failures, and existing context.
|
|
103
|
+
|
|
104
|
+
Depth controls how far to traverse from matched nodes:
|
|
105
|
+
- 1: direct matches only (fast)
|
|
106
|
+
- 2: matches + their neighbors (default, good balance)
|
|
107
|
+
- 3: two hops out (broader context, slower)
|
|
108
|
+
|
|
109
|
+
Example: recall(query="federation architecture", depth=2)`,
|
|
110
|
+
inputSchema: {
|
|
111
|
+
type: 'object',
|
|
112
|
+
properties: {
|
|
113
|
+
query: {
|
|
114
|
+
type: 'string',
|
|
115
|
+
description: 'What to recall — natural language query',
|
|
116
|
+
},
|
|
117
|
+
depth: {
|
|
118
|
+
type: 'number',
|
|
119
|
+
description: 'Traversal depth from matched nodes: 1-3 (default: 1)',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
required: ['query'],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: 'semantic_search',
|
|
127
|
+
description: `Embedding-based similarity search across the knowledge graph.
|
|
128
|
+
|
|
129
|
+
Use this for precise similarity matching — finds nodes whose content
|
|
130
|
+
is semantically close to the query, even if exact keywords differ.
|
|
131
|
+
|
|
132
|
+
More targeted than recall: returns ranked results without graph traversal.
|
|
133
|
+
|
|
134
|
+
Example: semantic_search(query="Docker container auth token", top_k=5, domain="devops")`,
|
|
135
|
+
inputSchema: {
|
|
136
|
+
type: 'object',
|
|
137
|
+
properties: {
|
|
138
|
+
query: {
|
|
139
|
+
type: 'string',
|
|
140
|
+
description: 'Natural language search query',
|
|
141
|
+
},
|
|
142
|
+
top_k: {
|
|
143
|
+
type: 'number',
|
|
144
|
+
description: 'Maximum number of results to return (default: 10)',
|
|
145
|
+
},
|
|
146
|
+
domain: {
|
|
147
|
+
type: 'string',
|
|
148
|
+
description: 'Filter results to a specific domain',
|
|
149
|
+
},
|
|
150
|
+
include_edges: {
|
|
151
|
+
type: 'boolean',
|
|
152
|
+
description: 'Include edges connected to matched nodes (default: false)',
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
required: ['query'],
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: 'enox_explore',
|
|
160
|
+
description: `Get all edges around an entity in the knowledge graph — see everything connected to it.
|
|
161
|
+
|
|
162
|
+
Use this to understand the full context of an entity: what it relates to,
|
|
163
|
+
what depends on it, what contradicts it, etc.
|
|
164
|
+
|
|
165
|
+
Returns all incoming and outgoing edges with connected node summaries.
|
|
166
|
+
|
|
167
|
+
Example: explore(entity="RFDB V2 engine")`,
|
|
168
|
+
inputSchema: {
|
|
169
|
+
type: 'object',
|
|
170
|
+
properties: {
|
|
171
|
+
entity: {
|
|
172
|
+
type: 'string',
|
|
173
|
+
description: 'Name or ID of the entity to explore',
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
required: ['entity'],
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: 'add_assertion',
|
|
181
|
+
description: `Create a precise edge between two nodes in the knowledge graph.
|
|
182
|
+
|
|
183
|
+
Use this when you need exact control over the graph structure:
|
|
184
|
+
- Specific relation type between two entities
|
|
185
|
+
- Confidence level on an assertion
|
|
186
|
+
- Domain scoping
|
|
187
|
+
|
|
188
|
+
Both "from" and "to" become nodes if they don't exist yet.
|
|
189
|
+
|
|
190
|
+
Example: add_assertion(from="Grafema", relation="uses", to="RFDB", context="RFDB is the storage engine for code graphs", confidence=1.0)`,
|
|
191
|
+
inputSchema: {
|
|
192
|
+
type: 'object',
|
|
193
|
+
properties: {
|
|
194
|
+
from: {
|
|
195
|
+
type: 'string',
|
|
196
|
+
description: 'Source entity name or ID',
|
|
197
|
+
},
|
|
198
|
+
relation: {
|
|
199
|
+
type: 'string',
|
|
200
|
+
description: 'Relation type for the edge',
|
|
201
|
+
enum: [...RELATION_TYPES],
|
|
202
|
+
},
|
|
203
|
+
to: {
|
|
204
|
+
type: 'string',
|
|
205
|
+
description: 'Target entity name or ID',
|
|
206
|
+
},
|
|
207
|
+
context: {
|
|
208
|
+
type: 'string',
|
|
209
|
+
description: 'Additional context or evidence for this assertion',
|
|
210
|
+
},
|
|
211
|
+
confidence: {
|
|
212
|
+
type: 'number',
|
|
213
|
+
description: 'Confidence level 0-1',
|
|
214
|
+
},
|
|
215
|
+
domain: {
|
|
216
|
+
type: 'string',
|
|
217
|
+
description: 'Knowledge domain this assertion belongs to',
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
required: ['from', 'relation', 'to'],
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
name: 'update_assertion',
|
|
225
|
+
description: `Update an existing edge in the knowledge graph.
|
|
226
|
+
|
|
227
|
+
Use this to change the context or confidence of a previously recorded assertion
|
|
228
|
+
without deleting and re-creating it.
|
|
229
|
+
|
|
230
|
+
Example: update_assertion(fact_id="edge-abc123", confidence=0.5, context="Partially confirmed after testing")`,
|
|
231
|
+
inputSchema: {
|
|
232
|
+
type: 'object',
|
|
233
|
+
properties: {
|
|
234
|
+
fact_id: {
|
|
235
|
+
type: 'string',
|
|
236
|
+
description: 'ID of the assertion/edge to update',
|
|
237
|
+
},
|
|
238
|
+
context: {
|
|
239
|
+
type: 'string',
|
|
240
|
+
description: 'Updated context or evidence',
|
|
241
|
+
},
|
|
242
|
+
confidence: {
|
|
243
|
+
type: 'number',
|
|
244
|
+
description: 'Updated confidence level 0-1',
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
required: ['fact_id'],
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: 'delete_assertion',
|
|
252
|
+
description: `Remove an edge from the knowledge graph.
|
|
253
|
+
|
|
254
|
+
Use this when an assertion is wrong, outdated, or no longer relevant.
|
|
255
|
+
Consider using update_assertion to lower confidence instead of deleting,
|
|
256
|
+
or add_assertion with "supersedes" relation to record the replacement.
|
|
257
|
+
|
|
258
|
+
Example: delete_assertion(fact_id="edge-abc123")`,
|
|
259
|
+
inputSchema: {
|
|
260
|
+
type: 'object',
|
|
261
|
+
properties: {
|
|
262
|
+
fact_id: {
|
|
263
|
+
type: 'string',
|
|
264
|
+
description: 'ID of the assertion/edge to remove',
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
required: ['fact_id'],
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: 'enox_query',
|
|
272
|
+
description: `Filter nodes in the knowledge graph by type, domain, or name.
|
|
273
|
+
|
|
274
|
+
Use this for exact filtering when you know what you're looking for.
|
|
275
|
+
Unlike semantic_search, this does exact/substring matching on fields.
|
|
276
|
+
|
|
277
|
+
Example: query_graph(type="decision", domain="engineering", limit=20)`,
|
|
278
|
+
inputSchema: {
|
|
279
|
+
type: 'object',
|
|
280
|
+
properties: {
|
|
281
|
+
type: {
|
|
282
|
+
type: 'string',
|
|
283
|
+
description: 'Filter by node type',
|
|
284
|
+
},
|
|
285
|
+
domain: {
|
|
286
|
+
type: 'string',
|
|
287
|
+
description: 'Filter by knowledge domain',
|
|
288
|
+
},
|
|
289
|
+
name: {
|
|
290
|
+
type: 'string',
|
|
291
|
+
description: 'Filter by node name (substring match)',
|
|
292
|
+
},
|
|
293
|
+
limit: {
|
|
294
|
+
type: 'number',
|
|
295
|
+
description: 'Maximum number of results (default: 50)',
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
name: 'enox_traverse',
|
|
302
|
+
description: `Graph traversal from a knowledge entity following specific edge types and direction.
|
|
303
|
+
|
|
304
|
+
Use this for structured exploration:
|
|
305
|
+
- "What does X depend on?" → traverse(start="X", direction="outgoing", edge_types=["depends_on"])
|
|
306
|
+
- "What supersedes X?" → traverse(start="X", direction="incoming", edge_types=["supersedes"])
|
|
307
|
+
- Full neighborhood: traverse(start="X", direction="both", max_depth=2)
|
|
308
|
+
|
|
309
|
+
Returns nodes with depth info (0 = start, 1 = direct, 2+ = transitive).
|
|
310
|
+
|
|
311
|
+
Example: traverse(start="RFDB", direction="outgoing", edge_types=["depends_on", "uses"], max_depth=3)`,
|
|
312
|
+
inputSchema: {
|
|
313
|
+
type: 'object',
|
|
314
|
+
properties: {
|
|
315
|
+
start: {
|
|
316
|
+
type: 'string',
|
|
317
|
+
description: 'Starting entity name or ID',
|
|
318
|
+
},
|
|
319
|
+
direction: {
|
|
320
|
+
type: 'string',
|
|
321
|
+
description: 'Traversal direction (default: "both")',
|
|
322
|
+
enum: ['outgoing', 'incoming', 'both'],
|
|
323
|
+
},
|
|
324
|
+
edge_types: {
|
|
325
|
+
type: 'array',
|
|
326
|
+
items: { type: 'string' },
|
|
327
|
+
description: 'Filter by edge/relation types. Omit for all.',
|
|
328
|
+
},
|
|
329
|
+
max_depth: {
|
|
330
|
+
type: 'number',
|
|
331
|
+
description: 'Maximum traversal depth (default: 2)',
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
required: ['start'],
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
name: 'enox_stats',
|
|
339
|
+
description: `Get statistics about the Enox knowledge graph.
|
|
340
|
+
|
|
341
|
+
Use this to:
|
|
342
|
+
- Check if the knowledge graph has content
|
|
343
|
+
- See node and edge counts by type
|
|
344
|
+
- Assess graph density and coverage
|
|
345
|
+
|
|
346
|
+
Returns: total nodes, total edges, counts by type, domain distribution.`,
|
|
347
|
+
inputSchema: {
|
|
348
|
+
type: 'object',
|
|
349
|
+
properties: {},
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
name: 'recent_activity',
|
|
354
|
+
description: `Get recently created or updated nodes and edges.
|
|
355
|
+
|
|
356
|
+
Use this at session start to see what other sessions have recorded recently.
|
|
357
|
+
Helps avoid duplicating work and provides continuity across sessions.
|
|
358
|
+
|
|
359
|
+
Example: recent_activity(since="2026-05-20T00:00:00Z", limit=10)`,
|
|
360
|
+
inputSchema: {
|
|
361
|
+
type: 'object',
|
|
362
|
+
properties: {
|
|
363
|
+
since: {
|
|
364
|
+
type: 'string',
|
|
365
|
+
description: 'ISO 8601 date — only show activity after this time',
|
|
366
|
+
},
|
|
367
|
+
limit: {
|
|
368
|
+
type: 'number',
|
|
369
|
+
description: 'Maximum number of results (default: 20)',
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
name: 'update_node',
|
|
376
|
+
description: `Update metadata on an existing node in the knowledge graph.
|
|
377
|
+
|
|
378
|
+
Use this to rename, re-domain, or add descriptions to existing nodes
|
|
379
|
+
without affecting their edges.
|
|
380
|
+
|
|
381
|
+
Example: update_node(node_id="node-abc123", description="V2 storage engine with segment-based persistence")`,
|
|
382
|
+
inputSchema: {
|
|
383
|
+
type: 'object',
|
|
384
|
+
properties: {
|
|
385
|
+
node_id: {
|
|
386
|
+
type: 'string',
|
|
387
|
+
description: 'ID of the node to update',
|
|
388
|
+
},
|
|
389
|
+
name: {
|
|
390
|
+
type: 'string',
|
|
391
|
+
description: 'Updated node name',
|
|
392
|
+
},
|
|
393
|
+
domain: {
|
|
394
|
+
type: 'string',
|
|
395
|
+
description: 'Updated knowledge domain',
|
|
396
|
+
},
|
|
397
|
+
description: {
|
|
398
|
+
type: 'string',
|
|
399
|
+
description: 'Updated node description',
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
required: ['node_id'],
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: 'crawl_entity',
|
|
407
|
+
description: `Run ontological crawl on a code entity — generate hypotheses and verify against code graph.
|
|
408
|
+
Uses the Grafema code graph for verification. Records findings in knowledge database.
|
|
409
|
+
Example: crawl_entity(entity="compactionEnricher", context="TypeScript enricher creating FEATURE nodes")`,
|
|
410
|
+
inputSchema: {
|
|
411
|
+
type: 'object',
|
|
412
|
+
properties: {
|
|
413
|
+
entity: { type: 'string', description: 'Entity name to crawl' },
|
|
414
|
+
context: { type: 'string', description: 'Brief description of what this entity is' },
|
|
415
|
+
depth: { type: 'number', description: 'How many perspectives to explore (default: 3)' },
|
|
416
|
+
},
|
|
417
|
+
required: ['entity'],
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
name: 'save_document',
|
|
422
|
+
description: `Store a document or artifact as a node in the knowledge graph.
|
|
423
|
+
|
|
424
|
+
Use this for longer-form content that should be persisted:
|
|
425
|
+
- ADRs (Architecture Decision Records)
|
|
426
|
+
- Postmortems and incident reports
|
|
427
|
+
- Specifications and design documents
|
|
428
|
+
- Session notes and artifacts
|
|
429
|
+
|
|
430
|
+
The document becomes a node with its content stored. Use relates_to to
|
|
431
|
+
link it to relevant entities in the graph.
|
|
432
|
+
|
|
433
|
+
Example: save_document(title="ADR: Federation via thick client", content="## Context\\n...", doc_type="adr", relates_to=["Grafema", "RFDB"])`,
|
|
434
|
+
inputSchema: {
|
|
435
|
+
type: 'object',
|
|
436
|
+
properties: {
|
|
437
|
+
title: {
|
|
438
|
+
type: 'string',
|
|
439
|
+
description: 'Document title (becomes the node name)',
|
|
440
|
+
},
|
|
441
|
+
content: {
|
|
442
|
+
type: 'string',
|
|
443
|
+
description: 'Full document content (markdown supported)',
|
|
444
|
+
},
|
|
445
|
+
doc_type: {
|
|
446
|
+
type: 'string',
|
|
447
|
+
description: 'Document type (default: "note")',
|
|
448
|
+
enum: ['adr', 'postmortem', 'spec', 'note', 'artifact'],
|
|
449
|
+
},
|
|
450
|
+
relates_to: {
|
|
451
|
+
type: 'array',
|
|
452
|
+
items: { type: 'string' },
|
|
453
|
+
description: 'Node IDs or names of related entities to link to',
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
required: ['title', 'content'],
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
];
|
package/src/definitions/index.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { GUARANTEE_TOOLS } from './guarantee-tools.js';
|
|
|
11
11
|
import { CONTEXT_TOOLS } from './context-tools.js';
|
|
12
12
|
import { PROJECT_TOOLS } from './project-tools.js';
|
|
13
13
|
import { GRAPH_TOOLS } from './graph-tools.js';
|
|
14
|
-
import {
|
|
14
|
+
import { ENOX_TOOLS } from './enox-tools.js';
|
|
15
15
|
import { NOTATION_TOOLS } from './notation-tools.js';
|
|
16
16
|
import { GRAPHQL_TOOLS } from './graphql-tools.js';
|
|
17
17
|
import { REGISTRY_TOOLS } from './registry-tools.js';
|
|
@@ -23,7 +23,7 @@ export const TOOLS: ToolDefinition[] = [
|
|
|
23
23
|
...CONTEXT_TOOLS,
|
|
24
24
|
...PROJECT_TOOLS,
|
|
25
25
|
...GRAPH_TOOLS,
|
|
26
|
-
...
|
|
26
|
+
...ENOX_TOOLS,
|
|
27
27
|
...NOTATION_TOOLS,
|
|
28
28
|
...GRAPHQL_TOOLS,
|
|
29
29
|
...REGISTRY_TOOLS,
|