@riligar/agents-memories 1.5.1 → 1.5.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riligar/agents-memories",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "description": "RiLiGar Agents Memories - A self-improving relational memory system for AI agents.",
5
5
  "module": "src/index.js",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -4,4 +4,4 @@ export { MemorySystem } from './sdk/memory-system.js'
4
4
  export { getSystemIdentity } from './core/identity.js'
5
5
  export * from './core/logic.js'
6
6
  export * from './database/schema.js'
7
- export { createMcpServer } from './server/mcp-server.js'
7
+ export { createMcpServer } from './sdk/mcp-server.js'
@@ -0,0 +1,192 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js'
2
+ import {
3
+ CallToolRequestSchema,
4
+ ListToolsRequestSchema,
5
+ ListResourcesRequestSchema,
6
+ ReadResourceRequestSchema
7
+ } from '@modelcontextprotocol/sdk/types.js'
8
+ import { createRequire } from 'module'
9
+ import { SIP_PROTOCOL } from '../core/sip.js'
10
+
11
+ const require = createRequire(import.meta.url)
12
+ const { version } = require('../../package.json')
13
+
14
+ export function createMcpServer(memorySystem) {
15
+ const server = new Server(
16
+ { name: 'RiLiGar Agents Memories', version },
17
+ { capabilities: { tools: {}, resources: {} } }
18
+ )
19
+
20
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
21
+ return {
22
+ tools: [
23
+ {
24
+ name: 'save',
25
+ description: `Persists a memory to the knowledge graph for future retrieval by any agent.
26
+
27
+ WHEN TO CALL: After completing a task, making a design or architectural decision, discovering a lesson learned, or receiving significant user feedback. Do not wait to be asked — save proactively.
28
+
29
+ HOW TO WRITE CONTENT: Always explain WHY, not just what. Bad: "we use SQLite". Good: "we use SQLite because it runs embedded with no server, simplifying deployment and reducing infrastructure cost". The rationale is what makes the memory useful later.
30
+
31
+ PATH: Organize with dot-notation (e.g., Project.Auth.Strategy, User.Preferences.Style, Lessons.Errors.Migration). Call \`list\` first to reuse an existing path instead of creating a near-duplicate.
32
+
33
+ PRIORITY (0–10): 8–10 for critical decisions that must not be forgotten. 4–7 for regular notes and observations. 1–3 for minor or temporary information. High-priority saves automatically raise the priority of semantically similar neighbors.
34
+
35
+ Supports batch saving: pass an array to \`content\` to persist multiple memories in one call.`,
36
+ inputSchema: {
37
+ type: 'object',
38
+ properties: {
39
+ content: {
40
+ description: 'The memory to persist. Include the WHY behind the decision or lesson, not just the what. Can be a single string or an array of strings/objects for batch saving.',
41
+ oneOf: [
42
+ { type: 'string' },
43
+ { type: 'array', items: { anyOf: [
44
+ { type: 'string' },
45
+ { type: 'object', properties: {
46
+ content: { type: 'string', description: 'The memory text. Include rationale.' },
47
+ path: { type: 'string', description: 'Dot-notation path (e.g., Project.Architecture.Storage).' },
48
+ owner_id: { type: 'string', description: 'Agent or user identifier.' },
49
+ priority: { type: 'integer', description: 'Importance 0–10.' }
50
+ }, required: ['content'] }
51
+ ] } }
52
+ ],
53
+ },
54
+ path: { type: 'string', description: 'Dot-notation path categorizing this memory (e.g., Project.Backend.API, Lessons.Errors.Auth, User.Preferences). Call `list` first to reuse existing paths.' },
55
+ owner_id: { type: 'string', description: 'Agent or user identifier for ownership. Use the system identity when saving on behalf of the agent itself.' },
56
+ priority: { type: 'integer', description: 'Importance from 0 to 10. Use 8–10 for critical decisions, 4–7 for regular notes, 1–3 for minor observations.' },
57
+ },
58
+ required: ['content'],
59
+ },
60
+ },
61
+ {
62
+ name: 'search',
63
+ description: `Semantically searches the knowledge graph and returns up to 5 results ranked by similarity (60%) and recency (40%), including any explicit relational links attached to each result.
64
+
65
+ WHEN TO CALL:
66
+ - BEFORE starting any task — to recover relevant past decisions, rationales, and lessons before acting.
67
+ - BEFORE answering any technical question — to avoid contradicting prior decisions.
68
+ - Whenever the user references "how we do things", "our approach", "past decisions", or when context seems to be missing.
69
+ - After receiving an error — to check if this problem was encountered and solved before.
70
+ - When the user asks about history, identity, preferences, values, or anything that implies continuity across sessions.
71
+
72
+ Do not wait to be asked. If the task implies prior context may exist, search first.`,
73
+ inputSchema: {
74
+ type: 'object',
75
+ properties: {
76
+ query: { type: 'string', description: 'Natural language query describing what you are looking for (e.g., "how we handle authentication", "past errors with database migration").' },
77
+ path_filter: { type: 'string', description: 'Optional path prefix to restrict results (e.g., "Project.Architecture" returns only memories under that subtree).' },
78
+ },
79
+ required: ['query'],
80
+ },
81
+ },
82
+ {
83
+ name: 'bridge',
84
+ description: `Creates a directed, explicit link between two memory paths — making a logical relationship retrievable even when the contents are not semantically similar.
85
+
86
+ WHEN TO CALL: When you discover that two stored topics have a dependency, hierarchy, or conflict that a semantic search would likely miss. Examples: a configuration path that depends_on an infrastructure path; a feature that implements a spec; two approaches that conflict_with each other.
87
+
88
+ COMMON RELATIONS: depends_on, part_of, implements, conflicts_with, supersedes, related_to.
89
+
90
+ Always call \`list\` first to confirm both paths exist. Do not bridge paths that have not been saved yet.`,
91
+ inputSchema: {
92
+ type: 'object',
93
+ properties: {
94
+ source_path: { type: 'string', description: 'The origin path of the relationship.' },
95
+ target_path: { type: 'string', description: 'The destination path of the relationship.' },
96
+ relation: { type: 'string', default: 'related_to', description: 'Relationship type: depends_on, part_of, implements, conflicts_with, supersedes, related_to.' },
97
+ },
98
+ required: ['source_path', 'target_path'],
99
+ },
100
+ },
101
+ {
102
+ name: 'list',
103
+ description: `Returns all unique memory path names currently in the knowledge graph.
104
+
105
+ WHEN TO CALL:
106
+ - Before saving, to pick the right existing path instead of creating a near-duplicate.
107
+ - Before bridging, to confirm the exact names of both paths.
108
+ - When you need an overview of what knowledge domains are available before searching.`,
109
+ inputSchema: { type: 'object', properties: {} },
110
+ },
111
+ {
112
+ name: 'inspect',
113
+ description: `Returns a Mermaid.js diagram of all explicit connections (bridges) between memory paths.
114
+
115
+ WHEN TO CALL: To audit the knowledge graph structure, verify that expected relationships were recorded, or detect isolated memories with no connections. Useful after a session of saves and bridges to confirm the graph is coherent and complete.`,
116
+ inputSchema: { type: 'object', properties: {} },
117
+ },
118
+ ],
119
+ }
120
+ })
121
+
122
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
123
+ return {
124
+ resources: [
125
+ {
126
+ uri: 'sip://protocol',
127
+ name: 'Self-Improvement Protocol (SIP)',
128
+ description: 'Protocolo de autoaperfeiçoamento contínuo para agentes RiLiGar.',
129
+ mimeType: 'text/markdown',
130
+ },
131
+ ],
132
+ }
133
+ })
134
+
135
+ server.setRequestHandler(ReadResourceRequestSchema, async request => {
136
+ if (request.params.uri === 'sip://protocol') {
137
+ return {
138
+ contents: [
139
+ {
140
+ uri: 'sip://protocol',
141
+ mimeType: 'text/markdown',
142
+ text: SIP_PROTOCOL,
143
+ },
144
+ ],
145
+ }
146
+ }
147
+ throw new Error('Resource not found')
148
+ })
149
+
150
+ server.setRequestHandler(CallToolRequestSchema, async request => {
151
+ const { name, arguments: args } = request.params
152
+
153
+ try {
154
+ if (name === 'save') {
155
+ const res = await memorySystem.save(args)
156
+ return { content: [{ type: 'text', text: `Saved ${res.count} memories. Semantic Magnet applied.` }] }
157
+ }
158
+
159
+ if (name === 'bridge') {
160
+ await memorySystem.bridge(args)
161
+ return { content: [{ type: 'text', text: `Bridge created: [${args.source_path}] --(${args.relation})--> [${args.target_path}]` }] }
162
+ }
163
+
164
+ if (name === 'search') {
165
+ const rows = await memorySystem.search(args)
166
+ const formattedResults = rows.map(r => {
167
+ const linkText = r.links.length > 0
168
+ ? `\n🔗 Related: ${r.links.map(l => `${l.path} (${l.relation_type})`).join(', ')}`
169
+ : ''
170
+ return `[${r.path} | P:${r.priority}] ${r.content}${linkText}`
171
+ })
172
+ return { content: [{ type: 'text', text: formattedResults.join('\n\n') || 'No results.' }] }
173
+ }
174
+
175
+ if (name === 'inspect') {
176
+ const mermaid = await memorySystem.inspect()
177
+ return { content: [{ type: 'text', text: `### Knowledge Graph\n\n\`\`\`mermaid\n${mermaid}\`\`\`` }] }
178
+ }
179
+
180
+ if (name === 'list') {
181
+ const paths = await memorySystem.list()
182
+ return { content: [{ type: 'text', text: paths.map(p => `- ${p}`).join('\n') || 'Empty.' }] }
183
+ }
184
+
185
+ throw new Error('Unknown tool.')
186
+ } catch (error) {
187
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true }
188
+ }
189
+ })
190
+
191
+ return server
192
+ }