agentdb 1.1.9 → 1.2.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.
@@ -430,34 +430,30 @@ class AgentDBCLI {
430
430
  // ============================================================================
431
431
  async function handleMcpCommands(subcommand, args) {
432
432
  if (!subcommand || subcommand === 'start') {
433
- log.header('\nšŸš€ Starting AgentDB MCP Server');
434
- log.info('Protocol: stdio (for Claude Desktop)');
435
- log.info('Tools: 15+ frontier memory and vector operations\n');
436
-
437
- console.log('šŸ’” Add to Claude Desktop config (~/.config/Claude/claude_desktop_config.json):');
438
- console.log(JSON.stringify({
439
- mcpServers: {
440
- agentdb: {
441
- command: 'npx',
442
- args: ['-y', 'agentdb@latest', 'mcp']
443
- }
433
+ // Start the actual MCP server
434
+ const { spawn } = await import('child_process');
435
+ const mcpServerPath = path.join(__dirname, '../mcp/agentdb-mcp-server.js');
436
+
437
+ const proc = spawn('node', [mcpServerPath], {
438
+ stdio: 'inherit',
439
+ env: {
440
+ ...process.env,
441
+ AGENTDB_PATH: process.env.AGENTDB_PATH || './agentdb.db'
444
442
  }
445
- }, null, 2));
446
- console.log('\nšŸ“š Available Tools:');
447
- console.log(' • reflexion_store - Store episodes with self-critique');
448
- console.log(' • reflexion_retrieve - Retrieve relevant past episodes');
449
- console.log(' • skill_create - Create reusable skills');
450
- console.log(' • skill_search - Search skills by similarity');
451
- console.log(' • causal_add_edge - Add causal relationships');
452
- console.log(' • causal_query - Query causal effects');
453
- console.log(' • recall_with_certificate - Causal utility recall');
454
- console.log(' • learner_discover - Auto-discover patterns');
455
- console.log(' • db_stats - Database statistics');
456
- console.log(' • ...and 6 more!\n');
457
-
458
- log.warning('Note: Full MCP server implementation coming in AgentDB v1.2.0');
459
- log.info('Current: Use CLI commands directly or via agentic-flow MCP');
460
- log.info('Workaround: npx agentic-flow@latest mcp (includes agentdb tools)');
443
+ });
444
+
445
+ proc.on('exit', (code) => {
446
+ process.exit(code || 0);
447
+ });
448
+
449
+ // Handle termination signals
450
+ process.on('SIGINT', () => {
451
+ proc.kill('SIGINT');
452
+ });
453
+
454
+ process.on('SIGTERM', () => {
455
+ proc.kill('SIGTERM');
456
+ });
461
457
  }
462
458
  else if (subcommand === 'list' || subcommand === 'tools') {
463
459
  console.log('\nšŸ“¦ AgentDB MCP Tools (15 total)\n');
@@ -0,0 +1,417 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * AgentDB MCP Server
4
+ * Production-ready MCP server for Claude Desktop integration
5
+ * Exposes AgentDB frontier memory features via MCP protocol
6
+ */
7
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
9
+ import {
10
+ CallToolRequestSchema,
11
+ ListToolsRequestSchema,
12
+ } from '@modelcontextprotocol/sdk/types.js';
13
+ import Database from 'better-sqlite3';
14
+ import { CausalMemoryGraph } from '../controllers/CausalMemoryGraph.js';
15
+ import { CausalRecall } from '../controllers/CausalRecall.js';
16
+ import { ReflexionMemory } from '../controllers/ReflexionMemory.js';
17
+ import { SkillLibrary } from '../controllers/SkillLibrary.js';
18
+ import { NightlyLearner } from '../controllers/NightlyLearner.js';
19
+ import { EmbeddingService } from '../controllers/EmbeddingService.js';
20
+ import * as path from 'path';
21
+
22
+ // ============================================================================
23
+ // Initialize AgentDB Controllers
24
+ // ============================================================================
25
+ const dbPath = process.env.AGENTDB_PATH || './agentdb.db';
26
+ const db = new Database(dbPath);
27
+
28
+ // Initialize embedding service
29
+ const embeddingService = new EmbeddingService({
30
+ model: 'Xenova/all-MiniLM-L6-v2',
31
+ cacheDir: './.agentdb/embeddings'
32
+ });
33
+ await embeddingService.initialize();
34
+
35
+ // Initialize all controllers
36
+ const causalGraph = new CausalMemoryGraph(db);
37
+ const causalRecall = new CausalRecall(db, embeddingService);
38
+ const reflexion = new ReflexionMemory(db, embeddingService);
39
+ const skills = new SkillLibrary(db, embeddingService);
40
+ const learner = new NightlyLearner(db, causalGraph, reflexion);
41
+
42
+ // ============================================================================
43
+ // MCP Server Setup
44
+ // ============================================================================
45
+ const server = new Server(
46
+ {
47
+ name: 'agentdb',
48
+ version: '1.2.0',
49
+ },
50
+ {
51
+ capabilities: {
52
+ tools: {},
53
+ },
54
+ }
55
+ );
56
+
57
+ // ============================================================================
58
+ // Tool Definitions
59
+ // ============================================================================
60
+ const tools = [
61
+ {
62
+ name: 'reflexion_store',
63
+ description: 'Store an episode with self-critique for reflexion-based learning',
64
+ inputSchema: {
65
+ type: 'object',
66
+ properties: {
67
+ session_id: { type: 'string', description: 'Session identifier' },
68
+ task: { type: 'string', description: 'Task description' },
69
+ reward: { type: 'number', description: 'Task reward (0-1)' },
70
+ success: { type: 'boolean', description: 'Whether task succeeded' },
71
+ critique: { type: 'string', description: 'Self-critique reflection' },
72
+ input: { type: 'string', description: 'Task input' },
73
+ output: { type: 'string', description: 'Task output' },
74
+ latency_ms: { type: 'number', description: 'Execution latency' },
75
+ tokens: { type: 'number', description: 'Tokens used' },
76
+ },
77
+ required: ['session_id', 'task', 'reward', 'success'],
78
+ },
79
+ },
80
+ {
81
+ name: 'reflexion_retrieve',
82
+ description: 'Retrieve relevant past episodes for learning from experience',
83
+ inputSchema: {
84
+ type: 'object',
85
+ properties: {
86
+ task: { type: 'string', description: 'Task to find similar episodes for' },
87
+ k: { type: 'number', description: 'Number of episodes to retrieve', default: 5 },
88
+ only_failures: { type: 'boolean', description: 'Only retrieve failures' },
89
+ only_successes: { type: 'boolean', description: 'Only retrieve successes' },
90
+ min_reward: { type: 'number', description: 'Minimum reward threshold' },
91
+ },
92
+ required: ['task'],
93
+ },
94
+ },
95
+ {
96
+ name: 'skill_create',
97
+ description: 'Create a reusable skill in the skill library',
98
+ inputSchema: {
99
+ type: 'object',
100
+ properties: {
101
+ name: { type: 'string', description: 'Skill name' },
102
+ description: { type: 'string', description: 'What the skill does' },
103
+ code: { type: 'string', description: 'Skill implementation code' },
104
+ success_rate: { type: 'number', description: 'Initial success rate' },
105
+ },
106
+ required: ['name', 'description'],
107
+ },
108
+ },
109
+ {
110
+ name: 'skill_search',
111
+ description: 'Search for applicable skills by semantic similarity',
112
+ inputSchema: {
113
+ type: 'object',
114
+ properties: {
115
+ task: { type: 'string', description: 'Task to find skills for' },
116
+ k: { type: 'number', description: 'Number of skills to return', default: 10 },
117
+ min_success_rate: { type: 'number', description: 'Minimum success rate filter' },
118
+ },
119
+ required: ['task'],
120
+ },
121
+ },
122
+ {
123
+ name: 'causal_add_edge',
124
+ description: 'Add a causal relationship between actions and outcomes',
125
+ inputSchema: {
126
+ type: 'object',
127
+ properties: {
128
+ cause: { type: 'string', description: 'Causal action/intervention' },
129
+ effect: { type: 'string', description: 'Observed effect/outcome' },
130
+ uplift: { type: 'number', description: 'Causal uplift magnitude' },
131
+ confidence: { type: 'number', description: 'Confidence in causal claim (0-1)', default: 0.95 },
132
+ sample_size: { type: 'number', description: 'Number of observations', default: 0 },
133
+ },
134
+ required: ['cause', 'effect', 'uplift'],
135
+ },
136
+ },
137
+ {
138
+ name: 'causal_query',
139
+ description: 'Query causal effects to understand what actions cause what outcomes',
140
+ inputSchema: {
141
+ type: 'object',
142
+ properties: {
143
+ cause: { type: 'string', description: 'Filter by cause (optional)' },
144
+ effect: { type: 'string', description: 'Filter by effect (optional)' },
145
+ min_confidence: { type: 'number', description: 'Minimum confidence', default: 0.5 },
146
+ min_uplift: { type: 'number', description: 'Minimum uplift', default: 0.0 },
147
+ limit: { type: 'number', description: 'Maximum results', default: 10 },
148
+ },
149
+ },
150
+ },
151
+ {
152
+ name: 'recall_with_certificate',
153
+ description: 'Retrieve memories with causal utility scoring and provenance certificate',
154
+ inputSchema: {
155
+ type: 'object',
156
+ properties: {
157
+ query: { type: 'string', description: 'Query for memory retrieval' },
158
+ k: { type: 'number', description: 'Number of results', default: 12 },
159
+ alpha: { type: 'number', description: 'Similarity weight', default: 0.7 },
160
+ beta: { type: 'number', description: 'Causal uplift weight', default: 0.2 },
161
+ gamma: { type: 'number', description: 'Recency weight', default: 0.1 },
162
+ },
163
+ required: ['query'],
164
+ },
165
+ },
166
+ {
167
+ name: 'learner_discover',
168
+ description: 'Automatically discover causal patterns from episode history',
169
+ inputSchema: {
170
+ type: 'object',
171
+ properties: {
172
+ min_attempts: { type: 'number', description: 'Minimum attempts required', default: 3 },
173
+ min_success_rate: { type: 'number', description: 'Minimum success rate', default: 0.6 },
174
+ min_confidence: { type: 'number', description: 'Minimum statistical confidence', default: 0.7 },
175
+ dry_run: { type: 'boolean', description: 'Preview without storing', default: false },
176
+ },
177
+ },
178
+ },
179
+ {
180
+ name: 'db_stats',
181
+ description: 'Get database statistics showing record counts',
182
+ inputSchema: {
183
+ type: 'object',
184
+ properties: {},
185
+ },
186
+ },
187
+ ];
188
+
189
+ // ============================================================================
190
+ // Tool Handlers
191
+ // ============================================================================
192
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
193
+ return { tools };
194
+ });
195
+
196
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
197
+ const { name, arguments: args } = request.params;
198
+
199
+ try {
200
+ switch (name) {
201
+ case 'reflexion_store': {
202
+ const episodeId = await reflexion.storeEpisode({
203
+ sessionId: args.session_id,
204
+ task: args.task,
205
+ reward: args.reward,
206
+ success: args.success,
207
+ critique: args.critique || '',
208
+ input: args.input || '',
209
+ output: args.output || '',
210
+ latencyMs: args.latency_ms || 0,
211
+ tokens: args.tokens || 0,
212
+ });
213
+ return {
214
+ content: [
215
+ {
216
+ type: 'text',
217
+ text: `āœ… Stored episode #${episodeId}\nTask: ${args.task}\nReward: ${args.reward}\nSuccess: ${args.success}`,
218
+ },
219
+ ],
220
+ };
221
+ }
222
+
223
+ case 'reflexion_retrieve': {
224
+ const episodes = await reflexion.retrieveRelevant({
225
+ task: args.task,
226
+ k: args.k || 5,
227
+ onlyFailures: args.only_failures,
228
+ onlySuccesses: args.only_successes,
229
+ minReward: args.min_reward,
230
+ });
231
+ return {
232
+ content: [
233
+ {
234
+ type: 'text',
235
+ text: `šŸ” Retrieved ${episodes.length} episodes:\n\n` +
236
+ episodes.map((ep, i) =>
237
+ `${i + 1}. Episode ${ep.id}\n Task: ${ep.task}\n Reward: ${ep.reward.toFixed(2)}\n Similarity: ${ep.similarity?.toFixed(3) || 'N/A'}`
238
+ ).join('\n\n'),
239
+ },
240
+ ],
241
+ };
242
+ }
243
+
244
+ case 'skill_create': {
245
+ const skillId = await skills.createSkill({
246
+ name: args.name,
247
+ description: args.description,
248
+ signature: { inputs: {}, outputs: {} },
249
+ code: args.code || '',
250
+ successRate: args.success_rate || 0.0,
251
+ uses: 0,
252
+ avgReward: 0.0,
253
+ avgLatencyMs: 0.0,
254
+ });
255
+ return {
256
+ content: [
257
+ {
258
+ type: 'text',
259
+ text: `āœ… Created skill #${skillId}: ${args.name}`,
260
+ },
261
+ ],
262
+ };
263
+ }
264
+
265
+ case 'skill_search': {
266
+ const foundSkills = await skills.searchSkills({
267
+ task: args.task,
268
+ k: args.k || 10,
269
+ minSuccessRate: args.min_success_rate || 0.0,
270
+ });
271
+ return {
272
+ content: [
273
+ {
274
+ type: 'text',
275
+ text: `šŸ” Found ${foundSkills.length} skills:\n\n` +
276
+ foundSkills.map((skill, i) =>
277
+ `${i + 1}. ${skill.name}\n ${skill.description}\n Success: ${(skill.successRate * 100).toFixed(1)}%`
278
+ ).join('\n\n'),
279
+ },
280
+ ],
281
+ };
282
+ }
283
+
284
+ case 'causal_add_edge': {
285
+ const edgeId = causalGraph.addCausalEdge({
286
+ fromMemoryId: 0,
287
+ fromMemoryType: args.cause,
288
+ toMemoryId: 0,
289
+ toMemoryType: args.effect,
290
+ similarity: 0,
291
+ uplift: args.uplift,
292
+ confidence: args.confidence || 0.95,
293
+ sampleSize: args.sample_size || 0,
294
+ evidenceIds: [],
295
+ });
296
+ return {
297
+ content: [
298
+ {
299
+ type: 'text',
300
+ text: `āœ… Added causal edge #${edgeId}\n${args.cause} → ${args.effect}\nUplift: ${args.uplift}`,
301
+ },
302
+ ],
303
+ };
304
+ }
305
+
306
+ case 'causal_query': {
307
+ const edges = causalGraph.queryCausalEffects({
308
+ interventionMemoryId: 0,
309
+ interventionMemoryType: args.cause || '',
310
+ outcomeMemoryId: args.effect ? 0 : undefined,
311
+ minConfidence: args.min_confidence || 0.5,
312
+ minUplift: args.min_uplift || 0.0,
313
+ });
314
+ const limited = edges.slice(0, args.limit || 10);
315
+ return {
316
+ content: [
317
+ {
318
+ type: 'text',
319
+ text: `šŸ” Found ${edges.length} causal edges:\n\n` +
320
+ limited.map((edge, i) =>
321
+ `${i + 1}. ${edge.cause} → ${edge.effect}\n Uplift: ${edge.uplift.toFixed(3)} (confidence: ${edge.confidence.toFixed(2)})`
322
+ ).join('\n\n'),
323
+ },
324
+ ],
325
+ };
326
+ }
327
+
328
+ case 'recall_with_certificate': {
329
+ const result = await causalRecall.recall(
330
+ 'mcp-' + Date.now(),
331
+ args.query,
332
+ args.k || 12,
333
+ undefined,
334
+ 'internal'
335
+ );
336
+ return {
337
+ content: [
338
+ {
339
+ type: 'text',
340
+ text: `šŸ” Retrieved ${result.candidates.length} results:\n\n` +
341
+ result.candidates.slice(0, 5).map((r, i) =>
342
+ `${i + 1}. ${r.type} ${r.id}\n Similarity: ${r.similarity.toFixed(3)}\n Uplift: ${r.uplift?.toFixed(3) || '0.000'}`
343
+ ).join('\n\n') +
344
+ `\n\nšŸ“œ Certificate ID: ${result.certificate.id}`,
345
+ },
346
+ ],
347
+ };
348
+ }
349
+
350
+ case 'learner_discover': {
351
+ const discovered = await learner.discover({
352
+ minAttempts: args.min_attempts || 3,
353
+ minSuccessRate: args.min_success_rate || 0.6,
354
+ minConfidence: args.min_confidence || 0.7,
355
+ dryRun: args.dry_run || false,
356
+ });
357
+ return {
358
+ content: [
359
+ {
360
+ type: 'text',
361
+ text: `šŸŒ™ Discovered ${discovered.length} causal patterns:\n\n` +
362
+ discovered.slice(0, 10).map((edge, i) =>
363
+ `${i + 1}. ${edge.cause} → ${edge.effect}\n Uplift: ${edge.uplift.toFixed(3)} (n=${edge.sampleSize})`
364
+ ).join('\n\n'),
365
+ },
366
+ ],
367
+ };
368
+ }
369
+
370
+ case 'db_stats': {
371
+ const stats = {
372
+ causal_edges: db.prepare('SELECT COUNT(*) as count FROM causal_edges').get().count,
373
+ causal_experiments: db.prepare('SELECT COUNT(*) as count FROM causal_experiments').get().count,
374
+ causal_observations: db.prepare('SELECT COUNT(*) as count FROM causal_observations').get().count,
375
+ episodes: db.prepare('SELECT COUNT(*) as count FROM episodes').get().count,
376
+ };
377
+ return {
378
+ content: [
379
+ {
380
+ type: 'text',
381
+ text: `šŸ“Š Database Statistics:\n\n` +
382
+ `Causal Edges: ${stats.causal_edges}\n` +
383
+ `Experiments: ${stats.causal_experiments}\n` +
384
+ `Observations: ${stats.causal_observations}\n` +
385
+ `Episodes: ${stats.episodes}`,
386
+ },
387
+ ],
388
+ };
389
+ }
390
+
391
+ default:
392
+ throw new Error(`Unknown tool: ${name}`);
393
+ }
394
+ } catch (error) {
395
+ return {
396
+ content: [
397
+ {
398
+ type: 'text',
399
+ text: `āŒ Error: ${error.message}`,
400
+ },
401
+ ],
402
+ isError: true,
403
+ };
404
+ }
405
+ });
406
+
407
+ // ============================================================================
408
+ // Start Server
409
+ // ============================================================================
410
+ async function main() {
411
+ const transport = new StdioServerTransport();
412
+ await server.connect(transport);
413
+ console.error('šŸš€ AgentDB MCP Server running on stdio');
414
+ console.error('šŸ“¦ 9 tools available for Claude Desktop');
415
+ }
416
+
417
+ main().catch(console.error);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agentdb",
3
- "version": "1.1.9",
4
- "description": "AgentDB - Frontier Memory Features: Causal reasoning, reflexion memory, skill library, explainable recall, and automated learning for AI agents. 150x faster vector search with HNSW indexing.",
3
+ "version": "1.2.0",
4
+ "description": "AgentDB - Frontier Memory Features with MCP Integration: Causal reasoning, reflexion memory, skill library, and automated learning. 150x faster vector search. Full Claude Desktop support via Model Context Protocol.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -55,10 +55,12 @@
55
55
  },
56
56
  "homepage": "https://agentdb.ruv.io",
57
57
  "dependencies": {
58
+ "@modelcontextprotocol/sdk": "^1.20.1",
58
59
  "@xenova/transformers": "^2.17.2",
59
60
  "better-sqlite3": "^11.7.0",
60
61
  "chalk": "^5.3.0",
61
- "commander": "^12.1.0"
62
+ "commander": "^12.1.0",
63
+ "zod": "^3.25.76"
62
64
  },
63
65
  "devDependencies": {
64
66
  "@types/better-sqlite3": "^7.6.11",