@justmpm/memory 0.1.2 → 0.2.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/AGENTS.md +45 -640
- package/CHANGELOG.md +42 -0
- package/CLAUDE.md +74 -180
- package/README.md +277 -281
- package/dist/index.js +216 -387
- package/dist/index.js.map +1 -1
- package/package.json +41 -40
- package/src/index.ts +538 -692
package/src/index.ts
CHANGED
|
@@ -1,692 +1,538 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Memory MCP Server - Sistema de memória persistente para subagents
|
|
5
|
-
*
|
|
6
|
-
* Permite que subagents salvem e recuperem aprendizados entre sessões.
|
|
7
|
-
* Cada agent tem sua própria memória, armazenada em .claude/agent-memory/<agent-name>/MEMORY.md
|
|
8
|
-
*
|
|
9
|
-
* @see https://modelcontextprotocol.io/
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
13
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
14
|
-
import {
|
|
15
|
-
CallToolRequestSchema,
|
|
16
|
-
ListToolsRequestSchema,
|
|
17
|
-
} from "@modelcontextprotocol/sdk/types.js";
|
|
18
|
-
import {
|
|
19
|
-
readFileSync,
|
|
20
|
-
writeFileSync,
|
|
21
|
-
existsSync,
|
|
22
|
-
mkdirSync,
|
|
23
|
-
|
|
24
|
-
} from "
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
29
|
-
//
|
|
30
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
*
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
return
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
.
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
};
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// Executa comando específico
|
|
543
|
-
let result: string;
|
|
544
|
-
|
|
545
|
-
switch (command) {
|
|
546
|
-
case "read": {
|
|
547
|
-
result = await handleRead(agentName);
|
|
548
|
-
break;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
case "write": {
|
|
552
|
-
const content = args?.content as string;
|
|
553
|
-
if (!content) {
|
|
554
|
-
result = `❌ ERRO: O parâmetro "content" é OBRIGATÓRIO para o comando "write".
|
|
555
|
-
|
|
556
|
-
EXEMPLO DE USO CORRETO:
|
|
557
|
-
{
|
|
558
|
-
"command": "write",
|
|
559
|
-
"agent": "sentinel",
|
|
560
|
-
"content": "# Memória do Sentinel\\n\\n## Padrões\\n- Sempre use Zod para validação\\n\\n## Bugs\\n- Bug XYZ ocorre quando..."
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
DICA: Use "write" para reorganizar memória grande ou reconstruir do zero.
|
|
564
|
-
Para adicionar uma entrada preservando o histórico, use "append".
|
|
565
|
-
`;
|
|
566
|
-
break;
|
|
567
|
-
}
|
|
568
|
-
result = await handleWrite(agentName, content);
|
|
569
|
-
break;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
case "append": {
|
|
573
|
-
const entry = args?.entry as string;
|
|
574
|
-
if (!entry) {
|
|
575
|
-
result = `❌ ERRO: O parâmetro "entry" é OBRIGATÓRIO para o comando "append".
|
|
576
|
-
|
|
577
|
-
EXEMPLO DE USO CORRETO:
|
|
578
|
-
{
|
|
579
|
-
"command": "append",
|
|
580
|
-
"agent": "sentinel",
|
|
581
|
-
"entry": "Padrão descoberto: Sempre use Zod para validar inputs do usuário em todos os componentes de formulário"
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
DICA: Use "append" para salvar aprendizados incrementais. O timestamp é adicionado automaticamente no formato:
|
|
585
|
-
## [2026-02-09 12:34:56]
|
|
586
|
-
Sua entrada aqui
|
|
587
|
-
|
|
588
|
-
Para salvar informações mais longas ou estruturadas, considere usar "write".
|
|
589
|
-
`;
|
|
590
|
-
break;
|
|
591
|
-
}
|
|
592
|
-
result = await handleAppend(agentName, entry);
|
|
593
|
-
break;
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
case "search": {
|
|
597
|
-
const query = args?.query as string;
|
|
598
|
-
if (!query) {
|
|
599
|
-
result = `❌ ERRO: O parâmetro "query" é OBRIGATÓRIO para o comando "search".
|
|
600
|
-
|
|
601
|
-
EXEMPLO DE USO CORRETO:
|
|
602
|
-
{
|
|
603
|
-
"command": "search",
|
|
604
|
-
"agent": "sentinel",
|
|
605
|
-
"query": "Zod"
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
DICA: A busca é case-insensitive e retorna até 20 ocorrências com o número da linha.
|
|
609
|
-
Exemplos de busca úteis: "padrão", "bug", "TypeScript", "Firebase", "erro"
|
|
610
|
-
`;
|
|
611
|
-
break;
|
|
612
|
-
}
|
|
613
|
-
result = await handleSearch(agentName, query);
|
|
614
|
-
break;
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
case "list": {
|
|
618
|
-
result = await handleList();
|
|
619
|
-
break;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
default:
|
|
623
|
-
result = `❌ Comando desconhecido: ${command}`;
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
return {
|
|
627
|
-
content: [
|
|
628
|
-
{
|
|
629
|
-
type: "text",
|
|
630
|
-
text: result,
|
|
631
|
-
},
|
|
632
|
-
],
|
|
633
|
-
};
|
|
634
|
-
});
|
|
635
|
-
|
|
636
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
637
|
-
// INICIALIZAÇÃO
|
|
638
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
639
|
-
|
|
640
|
-
async function main() {
|
|
641
|
-
// Verifica argumentos de linha de comando
|
|
642
|
-
const args = process.argv.slice(2);
|
|
643
|
-
|
|
644
|
-
// --version
|
|
645
|
-
if (args.includes("--version") || args.includes("-v")) {
|
|
646
|
-
console.log(`@justmpm/memory v${PACKAGE_VERSION}`);
|
|
647
|
-
process.exit(0);
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
// --help
|
|
651
|
-
if (args.includes("--help") || args.includes("-h")) {
|
|
652
|
-
console.log(`
|
|
653
|
-
@justmpm/memory - MCP Server para gerenciar memória persistente de subagents
|
|
654
|
-
|
|
655
|
-
Versão: ${PACKAGE_VERSION}
|
|
656
|
-
|
|
657
|
-
USO:
|
|
658
|
-
memory Inicia o servidor MCP (comunicação via stdio)
|
|
659
|
-
memory --version Mostra a versão do pacote
|
|
660
|
-
memory --help Mostra esta mensagem de ajuda
|
|
661
|
-
|
|
662
|
-
COMANDOS MCP:
|
|
663
|
-
- read Lê a memória de um agent
|
|
664
|
-
- write Substitui toda a memória
|
|
665
|
-
- append Adiciona uma entrada ao final
|
|
666
|
-
- search Busca texto na memória
|
|
667
|
-
- list Lista todos os agents com memória
|
|
668
|
-
|
|
669
|
-
DOCUMENTAÇÃO:
|
|
670
|
-
Para mais detalhes, consulte:
|
|
671
|
-
- CLAUDE.md (Documentação para IAs)
|
|
672
|
-
- AGENTS.md (Guia para subagents)
|
|
673
|
-
- README.md (Documentação principal)
|
|
674
|
-
|
|
675
|
-
REPOSITÓRIO:
|
|
676
|
-
https://github.com/justmpm/memory-mcp
|
|
677
|
-
|
|
678
|
-
LICENÇA:
|
|
679
|
-
MIT © Koda AI Studio
|
|
680
|
-
`);
|
|
681
|
-
process.exit(0);
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
const transport = new StdioServerTransport();
|
|
685
|
-
await server.connect(transport);
|
|
686
|
-
// Não faz log aqui pois o servidor se comunica via stdio
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
main().catch((error) => {
|
|
690
|
-
console.error("Erro fatal ao iniciar servidor:", error);
|
|
691
|
-
process.exit(1);
|
|
692
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Memory MCP Server - Sistema de memória persistente para subagents
|
|
5
|
+
*
|
|
6
|
+
* Permite que subagents salvem e recuperem aprendizados entre sessões.
|
|
7
|
+
* Cada agent tem sua própria memória, armazenada em .claude/agent-memory/<agent-name>/MEMORY.md
|
|
8
|
+
*
|
|
9
|
+
* @see https://modelcontextprotocol.io/
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
13
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
14
|
+
import {
|
|
15
|
+
CallToolRequestSchema,
|
|
16
|
+
ListToolsRequestSchema,
|
|
17
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
18
|
+
import {
|
|
19
|
+
readFileSync,
|
|
20
|
+
writeFileSync,
|
|
21
|
+
existsSync,
|
|
22
|
+
mkdirSync,
|
|
23
|
+
} from "fs";
|
|
24
|
+
import { join, dirname } from "path";
|
|
25
|
+
import { fileURLToPath } from "url";
|
|
26
|
+
import { z } from "zod";
|
|
27
|
+
|
|
28
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
29
|
+
// SCHEMAS DE VALIDAÇÃO (Zod)
|
|
30
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Schema para tool memory_read
|
|
34
|
+
*/
|
|
35
|
+
const MemoryReadSchema = z.object({
|
|
36
|
+
agent: z.string().optional().describe(
|
|
37
|
+
'Seu nome de agent (ex: "sentinel", "fix-worker"). Opcional - usa "unknown" se não informado.'
|
|
38
|
+
),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Schema para tool memory_append
|
|
43
|
+
*/
|
|
44
|
+
const MemoryAppendSchema = z.object({
|
|
45
|
+
agent: z.string().optional().describe(
|
|
46
|
+
'Seu nome de agent (ex: "sentinel", "fix-worker"). Opcional - usa "unknown" se não informado.'
|
|
47
|
+
),
|
|
48
|
+
entry: z.string().min(1).describe(
|
|
49
|
+
'Texto da informação a salvar. Ex: "Padrão: sempre use try/catch em funções async" ou "Bug: erro quando usuário clica 2x". Será adicionado com timestamp automaticamente.'
|
|
50
|
+
),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Schema para tool memory_search
|
|
55
|
+
*/
|
|
56
|
+
const MemorySearchSchema = z.object({
|
|
57
|
+
agent: z.string().optional().describe(
|
|
58
|
+
'Seu nome de agent (ex: "sentinel", "fix-worker"). Opcional - usa "unknown" se não informado.'
|
|
59
|
+
),
|
|
60
|
+
query: z.string().min(1).describe(
|
|
61
|
+
'Palavra-chave para buscar na sua memória. Ex: "Zod", "bug", "Firebase". Retorna até 20 resultados com número da linha.'
|
|
62
|
+
),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Schema para tool memory_write
|
|
67
|
+
*/
|
|
68
|
+
const MemoryWriteSchema = z.object({
|
|
69
|
+
agent: z.string().optional().describe(
|
|
70
|
+
'Seu nome de agent (ex: "sentinel", "fix-worker"). Opcional - usa "unknown" se não informado.'
|
|
71
|
+
),
|
|
72
|
+
content: z.string().min(1).describe(
|
|
73
|
+
'Conteúdo completo em markdown para substituir a memória existente. Use para reorganizar, limpar ou reconstruir memória do zero.'
|
|
74
|
+
),
|
|
75
|
+
backup: z.boolean().optional().default(false).describe(
|
|
76
|
+
'Se true, cria um backup do conteúdo atual antes de sobrescrever. O backup é salvo como MEMORY.md.backup no mesmo diretório.'
|
|
77
|
+
),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
81
|
+
// VERSÃO DO PROJETO
|
|
82
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Lê a versão do package.json dinamicamente
|
|
86
|
+
*/
|
|
87
|
+
function getPackageVersion(): string {
|
|
88
|
+
try {
|
|
89
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
90
|
+
const __dirname = dirname(__filename);
|
|
91
|
+
const packagePath = join(__dirname, "..", "package.json");
|
|
92
|
+
const packageJson = JSON.parse(readFileSync(packagePath, "utf-8"));
|
|
93
|
+
return packageJson.version || "0.1.0";
|
|
94
|
+
} catch {
|
|
95
|
+
return "0.1.0";
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const PACKAGE_VERSION = getPackageVersion();
|
|
100
|
+
|
|
101
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
102
|
+
// FUNÇÕES UTILITÁRIAS
|
|
103
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Normaliza nome do agent para usar como nome de pasta
|
|
107
|
+
* Ex: "Sentinel" → "sentinel", "QA-Tester" → "qa-tester"
|
|
108
|
+
*/
|
|
109
|
+
function normalizeAgentName(agentName: string): string {
|
|
110
|
+
return agentName
|
|
111
|
+
.toLowerCase()
|
|
112
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
113
|
+
.replace(/^-|-$/g, "");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Retorna o caminho do diretório de memória para um agent
|
|
118
|
+
*/
|
|
119
|
+
function getAgentMemoryDir(agentName: string): string {
|
|
120
|
+
const normalizedName = normalizeAgentName(agentName);
|
|
121
|
+
return join(process.cwd(), ".claude", "agent-memory", normalizedName);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Retorna o caminho do arquivo MEMORY.md de um agent
|
|
126
|
+
*/
|
|
127
|
+
function getAgentMemoryPath(agentName: string): string {
|
|
128
|
+
return join(getAgentMemoryDir(agentName), "MEMORY.md");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Garante que o diretório existe
|
|
133
|
+
*/
|
|
134
|
+
function ensureAgentMemoryDir(agentName: string): void {
|
|
135
|
+
const dir = getAgentMemoryDir(agentName);
|
|
136
|
+
if (!existsSync(dir)) {
|
|
137
|
+
mkdirSync(dir, { recursive: true });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Formata timestamp para uso em entradas de memória
|
|
143
|
+
*/
|
|
144
|
+
function formatTimestamp(): string {
|
|
145
|
+
const now = new Date();
|
|
146
|
+
return now.toISOString().replace("T", " ").slice(0, 19);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Limita memória a ~200 linhas (últimas entradas)
|
|
151
|
+
*/
|
|
152
|
+
function limitMemoryLines(content: string, maxLines = 200): string {
|
|
153
|
+
const lines = content.split("\n");
|
|
154
|
+
if (lines.length <= maxLines) return content;
|
|
155
|
+
const keepCount = Math.floor(maxLines * 0.8); // 160 linhas
|
|
156
|
+
const removed = lines.length - keepCount;
|
|
157
|
+
return `# Memória (últimas ${keepCount} de ${lines.length} linhas)
|
|
158
|
+
|
|
159
|
+
[... ${removed} linhas anteriores removidas ...]
|
|
160
|
+
|
|
161
|
+
${lines.slice(-keepCount).join("\n")}`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
165
|
+
// HANDLERS DAS OPERAÇÕES
|
|
166
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Handler: read - Lê a memória do agent atual
|
|
170
|
+
*/
|
|
171
|
+
async function handleRead(agentName: string): Promise<string> {
|
|
172
|
+
const memoryPath = getAgentMemoryPath(agentName);
|
|
173
|
+
|
|
174
|
+
if (!existsSync(memoryPath)) {
|
|
175
|
+
return `📝 Memória vazia para agent "${agentName}".
|
|
176
|
+
|
|
177
|
+
Use \`command="append", entry="..."\` para criar a primeira entrada.`;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
const content = readFileSync(memoryPath, "utf-8");
|
|
182
|
+
const lines = content.split("\n").length;
|
|
183
|
+
return `📝 Memória de "${agentName}" (${lines} linhas):
|
|
184
|
+
|
|
185
|
+
─────────────────────────────────────────────────────────────────
|
|
186
|
+
|
|
187
|
+
${content}`;
|
|
188
|
+
} catch (error) {
|
|
189
|
+
return `❌ Erro ao ler memória: ${(error as Error).message}`;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Handler: write - Substitui toda a memória
|
|
195
|
+
*/
|
|
196
|
+
async function handleWrite(
|
|
197
|
+
agentName: string,
|
|
198
|
+
content: string,
|
|
199
|
+
backup: boolean = false
|
|
200
|
+
): Promise<string> {
|
|
201
|
+
try {
|
|
202
|
+
ensureAgentMemoryDir(agentName);
|
|
203
|
+
const memoryPath = getAgentMemoryPath(agentName);
|
|
204
|
+
|
|
205
|
+
// Cria backup se solicitado e arquivo existir
|
|
206
|
+
let backupMessage = "";
|
|
207
|
+
if (backup && existsSync(memoryPath)) {
|
|
208
|
+
const backupPath = memoryPath + ".backup";
|
|
209
|
+
const existingContent = readFileSync(memoryPath, "utf-8");
|
|
210
|
+
writeFileSync(backupPath, existingContent, "utf-8");
|
|
211
|
+
backupMessage = `\n💾 Backup criado: MEMORY.md.backup`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const limited = limitMemoryLines(content);
|
|
215
|
+
writeFileSync(memoryPath, limited, "utf-8");
|
|
216
|
+
|
|
217
|
+
const lines = limited.split("\n").length;
|
|
218
|
+
return `✅ Memória de "${agentName}" atualizada (${lines} linhas).${backupMessage}
|
|
219
|
+
|
|
220
|
+
${lines >= 200 ? "⚠️ Memória atingiu o limite de 200 linhas." : ""}`;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
return `❌ Erro ao escrever memória: ${(error as Error).message}`;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Handler: append - Adiciona uma entrada no final
|
|
228
|
+
*/
|
|
229
|
+
async function handleAppend(
|
|
230
|
+
agentName: string,
|
|
231
|
+
entry: string
|
|
232
|
+
): Promise<string> {
|
|
233
|
+
try {
|
|
234
|
+
ensureAgentMemoryDir(agentName);
|
|
235
|
+
const memoryPath = getAgentMemoryPath(agentName);
|
|
236
|
+
|
|
237
|
+
// Lê conteúdo existente
|
|
238
|
+
let existingContent = "";
|
|
239
|
+
if (existsSync(memoryPath)) {
|
|
240
|
+
existingContent = readFileSync(memoryPath, "utf-8");
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Adiciona nova entrada com timestamp
|
|
244
|
+
const timestamp = formatTimestamp();
|
|
245
|
+
const newEntry = `\n## [${timestamp}]\n${entry}\n`;
|
|
246
|
+
const newContent = existingContent + newEntry;
|
|
247
|
+
|
|
248
|
+
// Salva com limite
|
|
249
|
+
const limited = limitMemoryLines(newContent);
|
|
250
|
+
writeFileSync(memoryPath, limited, "utf-8");
|
|
251
|
+
|
|
252
|
+
return `✅ Entrada adicionada à memória de "${agentName}".
|
|
253
|
+
|
|
254
|
+
**Timestamp:** ${timestamp}
|
|
255
|
+
**Entry:** ${entry.slice(0, 100)}${entry.length > 100 ? "..." : ""}`;
|
|
256
|
+
} catch (error) {
|
|
257
|
+
return `❌ Erro ao adicionar entrada: ${(error as Error).message}`;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Handler: search - Busca texto na memória
|
|
263
|
+
*/
|
|
264
|
+
async function handleSearch(
|
|
265
|
+
agentName: string,
|
|
266
|
+
query: string
|
|
267
|
+
): Promise<string> {
|
|
268
|
+
const memoryPath = getAgentMemoryPath(agentName);
|
|
269
|
+
|
|
270
|
+
if (!existsSync(memoryPath)) {
|
|
271
|
+
return `📝 Memória vazia para agent "${agentName}".`;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
const content = readFileSync(memoryPath, "utf-8");
|
|
276
|
+
const lines = content.split("\n");
|
|
277
|
+
const queryLower = query.toLowerCase();
|
|
278
|
+
|
|
279
|
+
const matches = lines
|
|
280
|
+
.map((line, idx) => ({ line, idx }))
|
|
281
|
+
.filter(({ line }) => line.toLowerCase().includes(queryLower));
|
|
282
|
+
|
|
283
|
+
if (matches.length === 0) {
|
|
284
|
+
return `📝 Nenhuma ocorrência de "${query}" encontrada na memória de "${agentName}".`;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const results = matches
|
|
288
|
+
.slice(0, 20) // Máximo 20 resultados
|
|
289
|
+
.map(({ line, idx }) => ` L${idx + 1}: ${line}`)
|
|
290
|
+
.join("\n");
|
|
291
|
+
|
|
292
|
+
const more = matches.length > 20 ? `\n... e mais ${matches.length - 20} ocorrências` : "";
|
|
293
|
+
|
|
294
|
+
return `📝 Busca por "${query}" em "${agentName}" (${matches.length} ocorrências):
|
|
295
|
+
|
|
296
|
+
${results}${more}`;
|
|
297
|
+
} catch (error) {
|
|
298
|
+
return `❌ Erro ao buscar: ${(error as Error).message}`;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
304
|
+
// SERVIDOR MCP
|
|
305
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
306
|
+
|
|
307
|
+
// Cria o servidor MCP
|
|
308
|
+
const server = new Server(
|
|
309
|
+
{
|
|
310
|
+
name: "@justmpm/memory",
|
|
311
|
+
version: PACKAGE_VERSION,
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
capabilities: {
|
|
315
|
+
tools: {},
|
|
316
|
+
},
|
|
317
|
+
}
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Handler: ListTools - Lista todas as tools disponíveis
|
|
322
|
+
*/
|
|
323
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
324
|
+
return {
|
|
325
|
+
tools: [
|
|
326
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
327
|
+
// TOOL: memory_read
|
|
328
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
329
|
+
{
|
|
330
|
+
name: "memory_read",
|
|
331
|
+
description: `Lê todo o conteúdo da sua memória persistente. Use sempre ao iniciar uma sessão para recuperar contexto anterior.
|
|
332
|
+
|
|
333
|
+
RETORNA: Conteúdo completo do MEMORY.md localizado em .claude/agent-memory/<agent-name>/MEMORY.md.
|
|
334
|
+
|
|
335
|
+
Se a memória não existir, retorna mensagem de memória vazia com sugestão para usar memory_append.
|
|
336
|
+
|
|
337
|
+
Limite: Máximo 200 linhas. Ao atingir, mantém apenas as últimas 160 entradas.
|
|
338
|
+
|
|
339
|
+
Parâmetro "agent": Seu nome de agent (opcional, padrão: "unknown").`,
|
|
340
|
+
inputSchema: MemoryReadSchema,
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
344
|
+
// TOOL: memory_append
|
|
345
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
346
|
+
{
|
|
347
|
+
name: "memory_append",
|
|
348
|
+
description: `Adiciona uma entrada no final da sua memória com timestamp automático "## [YYYY-MM-DD HH:MM:SS]".
|
|
349
|
+
|
|
350
|
+
USE QUANDO APRENDER algo importante: padrões de código, bugs recorrentes, decisões arquiteturais, preferências do usuário, configurações importantes.
|
|
351
|
+
|
|
352
|
+
EXEMPLOS DE ENTRADAS VÁLIDAS:
|
|
353
|
+
- "Padrão: Este projeto usa App Router com estrutura /features/[domain]/"
|
|
354
|
+
- "Decisão: Escolhemos Zustand em vez de Redux porque é mais leve"
|
|
355
|
+
- "Bug: Firestore update falha silenciosamente quando array está vazio"
|
|
356
|
+
|
|
357
|
+
NÃO salve: Coisas triviais, informações temporárias, logs de conversa.
|
|
358
|
+
|
|
359
|
+
Parâmetro "agent": Seu nome de agent (opcional, padrão: "unknown").
|
|
360
|
+
Parâmetro "entry": OBRIGATÓRIO - Texto da informação a salvar.`,
|
|
361
|
+
inputSchema: MemoryAppendSchema,
|
|
362
|
+
},
|
|
363
|
+
|
|
364
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
365
|
+
// TOOL: memory_search
|
|
366
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
367
|
+
{
|
|
368
|
+
name: "memory_search",
|
|
369
|
+
description: `Busca um termo na sua memória sem precisar ler todo o conteúdo.
|
|
370
|
+
|
|
371
|
+
RETORNA: Até 20 ocorrências encontradas com número da linha. Busca case-insensitive.
|
|
372
|
+
|
|
373
|
+
EXEMPLOS DE BUSCA ÚTEIS:
|
|
374
|
+
- "Zod" → encontrar tudo sobre validação
|
|
375
|
+
- "bug" → encontrar bugs documentados
|
|
376
|
+
- "Firebase" → encontrar configurações
|
|
377
|
+
- "TypeScript" → encontrar padrões de tipagem
|
|
378
|
+
|
|
379
|
+
Se não encontrar, retorna mensagem de que nenhuma ocorrência foi encontrada.
|
|
380
|
+
|
|
381
|
+
Parâmetro "agent": Seu nome de agent (opcional, padrão: "unknown").
|
|
382
|
+
Parâmetro "query": OBRIGATÓRIO - Termo ou palavra-chave a buscar.`,
|
|
383
|
+
inputSchema: MemorySearchSchema,
|
|
384
|
+
},
|
|
385
|
+
|
|
386
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
387
|
+
// TOOL: memory_write
|
|
388
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
389
|
+
{
|
|
390
|
+
name: "memory_write",
|
|
391
|
+
description: `SUBSTITUI TODO o conteúdo da sua memória. APAGA tudo que estava antes - use com cautela.
|
|
392
|
+
|
|
393
|
+
USE QUANDO: Memória está grande (~150+ linhas) e precisa reorganizar, ou quer remover entradas obsoletas.
|
|
394
|
+
|
|
395
|
+
DICAS:
|
|
396
|
+
- Use "backup: true" para criar MEMORY.md.backup antes de sobrescrever
|
|
397
|
+
- Leia primeiro com memory_read para não perder conteúdo importante
|
|
398
|
+
- Organize em seções: ## Padrões, ## Bugs, ## Decisões, ## Configurações
|
|
399
|
+
|
|
400
|
+
EXEMPLO DE ESTRUTURA:
|
|
401
|
+
# Memória do Agent
|
|
402
|
+
|
|
403
|
+
## Padrões de Código
|
|
404
|
+
- Sempre use TypeScript estrito
|
|
405
|
+
|
|
406
|
+
## Bugs Conhecidos
|
|
407
|
+
- Bug XYZ: ocorre quando array vazio
|
|
408
|
+
Workaround: verificar length antes de usar
|
|
409
|
+
|
|
410
|
+
## Decisões
|
|
411
|
+
- Zustand em vez de Redux (mais leve)
|
|
412
|
+
|
|
413
|
+
Parâmetro "agent": Seu nome de agent (opcional, padrão: "unknown").
|
|
414
|
+
Parâmetro "content": OBRIGATÓRIO - Novo conteúdo completo em markdown.
|
|
415
|
+
Parâmetro "backup": Opcional (padrão: false) - Se true, cria backup antes de sobrescrever.`,
|
|
416
|
+
inputSchema: MemoryWriteSchema,
|
|
417
|
+
},
|
|
418
|
+
],
|
|
419
|
+
};
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Handler: CallTool - Executa uma tool
|
|
424
|
+
*/
|
|
425
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
426
|
+
const { name, arguments: args } = request.params;
|
|
427
|
+
const agentName = (args?.agent as string) || "unknown";
|
|
428
|
+
|
|
429
|
+
try {
|
|
430
|
+
switch (name) {
|
|
431
|
+
case "memory_read": {
|
|
432
|
+
const parsed = MemoryReadSchema.safeParse(args);
|
|
433
|
+
if (!parsed.success) {
|
|
434
|
+
throw new Error(`Parâmetros inválidos: ${parsed.error.issues.map((e: { message: string }) => e.message).join(", ")}`);
|
|
435
|
+
}
|
|
436
|
+
const result = await handleRead(agentName);
|
|
437
|
+
return { content: [{ type: "text", text: result }] };
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
case "memory_append": {
|
|
441
|
+
const parsed = MemoryAppendSchema.safeParse(args);
|
|
442
|
+
if (!parsed.success) {
|
|
443
|
+
throw new Error(`Parâmetros inválidos: ${parsed.error.issues.map((e: { message: string }) => e.message).join(", ")}`);
|
|
444
|
+
}
|
|
445
|
+
const result = await handleAppend(agentName, parsed.data.entry);
|
|
446
|
+
return { content: [{ type: "text", text: result }] };
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
case "memory_search": {
|
|
450
|
+
const parsed = MemorySearchSchema.safeParse(args);
|
|
451
|
+
if (!parsed.success) {
|
|
452
|
+
throw new Error(`Parâmetros inválidos: ${parsed.error.issues.map((e: { message: string }) => e.message).join(", ")}`);
|
|
453
|
+
}
|
|
454
|
+
const result = await handleSearch(agentName, parsed.data.query);
|
|
455
|
+
return { content: [{ type: "text", text: result }] };
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
case "memory_write": {
|
|
459
|
+
const parsed = MemoryWriteSchema.safeParse(args);
|
|
460
|
+
if (!parsed.success) {
|
|
461
|
+
throw new Error(`Parâmetros inválidos: ${parsed.error.issues.map((e: { message: string }) => e.message).join(", ")}`);
|
|
462
|
+
}
|
|
463
|
+
const result = await handleWrite(agentName, parsed.data.content, parsed.data.backup);
|
|
464
|
+
return { content: [{ type: "text", text: result }] };
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
default:
|
|
468
|
+
throw new Error(`Tool desconhecida: ${name}`);
|
|
469
|
+
}
|
|
470
|
+
} catch (error) {
|
|
471
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
472
|
+
return {
|
|
473
|
+
content: [
|
|
474
|
+
{
|
|
475
|
+
type: "text",
|
|
476
|
+
text: `❌ Erro ao executar tool "${name}": ${errorMessage}`,
|
|
477
|
+
},
|
|
478
|
+
],
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
484
|
+
// INICIALIZAÇÃO
|
|
485
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
486
|
+
|
|
487
|
+
async function main() {
|
|
488
|
+
// Verifica argumentos de linha de comando
|
|
489
|
+
const args = process.argv.slice(2);
|
|
490
|
+
|
|
491
|
+
// --version
|
|
492
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
493
|
+
console.log(`@justmpm/memory v${PACKAGE_VERSION}`);
|
|
494
|
+
process.exit(0);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// --help
|
|
498
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
499
|
+
console.log(`
|
|
500
|
+
@justmpm/memory - MCP Server para gerenciar memória persistente de subagents
|
|
501
|
+
|
|
502
|
+
Versão: ${PACKAGE_VERSION}
|
|
503
|
+
|
|
504
|
+
USO:
|
|
505
|
+
memory Inicia o servidor MCP (comunicação via stdio)
|
|
506
|
+
memory --version Mostra a versão do pacote
|
|
507
|
+
memory --help Mostra esta mensagem de ajuda
|
|
508
|
+
|
|
509
|
+
TOOLS MCP:
|
|
510
|
+
- memory_read Lê a memória de um agent
|
|
511
|
+
- memory_write Substitui toda a memória
|
|
512
|
+
- memory_append Adiciona uma entrada ao final
|
|
513
|
+
- memory_search Busca texto na memória
|
|
514
|
+
|
|
515
|
+
DOCUMENTAÇÃO:
|
|
516
|
+
Para mais detalhes, consulte:
|
|
517
|
+
- CLAUDE.md (Documentação para IAs)
|
|
518
|
+
- AGENTS.md (Guia para subagents)
|
|
519
|
+
- README.md (Documentação principal)
|
|
520
|
+
|
|
521
|
+
REPOSITÓRIO:
|
|
522
|
+
https://github.com/justmpm/memory-mcp
|
|
523
|
+
|
|
524
|
+
LICENÇA:
|
|
525
|
+
MIT © Koda AI Studio
|
|
526
|
+
`);
|
|
527
|
+
process.exit(0);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
const transport = new StdioServerTransport();
|
|
531
|
+
await server.connect(transport);
|
|
532
|
+
// Não faz log aqui pois o servidor se comunica via stdio
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
main().catch((error) => {
|
|
536
|
+
console.error("Erro fatal ao iniciar servidor:", error);
|
|
537
|
+
process.exit(1);
|
|
538
|
+
});
|