Day 1: "Build the user authentication system"
Agent: [Membangun otentikasi JWT, membuat tabel pengguna, mengimplementasikan token refresh] Day 2: "Lanjutkan dari kemarin"
Agent: "Saya tidak memiliki konteks dari sesi sebelumnya. Bisakah Anda menempelkan apa yang kita lakukan?"
Day 1: "Build the user authentication system"
Agent: [Membangun otentikasi JWT, membuat tabel pengguna, mengimplementasikan token refresh] Day 2: "Lanjutkan dari kemarin"
Agent: "Saya tidak memiliki konteks dari sesi sebelumnya. Bisakah Anda menempelkan apa yang kita lakukan?"
Day 1: "Build the user authentication system"
Agent: [Membangun otentikasi JWT, membuat tabel pengguna, mengimplementasikan token refresh] Day 2: "Lanjutkan dari kemarin"
Agent: "Saya tidak memiliki konteks dari sesi sebelumnya. Bisakah Anda menempelkan apa yang kita lakukan?"
┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐
│ AI Agent │ │ MCP Memory │ │ Storage │
│ (Claude Code) │◄───────►│ Server │◄───────►│ (SQLite) │
└─────────────────┘ JSON └──────────────────┘ I/O └─────────────┘
┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐
│ AI Agent │ │ MCP Memory │ │ Storage │
│ (Claude Code) │◄───────►│ Server │◄───────►│ (SQLite) │
└─────────────────┘ JSON └──────────────────┘ I/O └─────────────┘
┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐
│ AI Agent │ │ MCP Memory │ │ Storage │
│ (Claude Code) │◄───────►│ Server │◄───────►│ (SQLite) │
└─────────────────┘ JSON └──────────────────┘ I/O └─────────────┘
npm install -g @example/mcp-memory-server
npm install -g @example/mcp-memory-server
npm install -g @example/mcp-memory-server
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import fs from "fs/promises";
import path from "path"; const MEMORY_FILE = path.join(process.env.HOME, ".mcp-memory", "memories.json"); const server = new McpServer({ name: "memory", version: "1.0.0"
}); // Ensure memory file exists
async function initMemory() { await fs.mkdir(path.dirname(MEMORY_FILE), { recursive: true }); try { await fs.access(MEMORY_FILE); } catch { await fs.writeFile(MEMORY_FILE, JSON.stringify([])); }
} // Tool: remember
server.tool( "remember", { content: z.string().describe("Information to store"), tags: z.array(z.string()).describe("Tags for retrieval (e.g., ['backend', 'auth'])"), agent: z.string().optional().describe("Agent name for tagging") }, async ({ content, tags, agent }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const memory = { id: Date.now().toString(), content, tags, agent, timestamp: new Date().toISOString() }; memories.push(memory); await fs.writeFile(MEMORY_FILE, JSON.stringify(memories, null, 2)); return { content: [{ type: "text", text: `Stored memory with tags: ${tags.join(", ")}` }] }; }
); // Tool: recall
server.tool( "recall", { query: z.string().describe("Search query or tag to find"), agent: z.string().optional().describe("Filter by agent name") }, async ({ query, agent }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const results = memories.filter(m => { const matchesQuery = m.content.toLowerCase().includes(query.toLowerCase()) || m.tags.some(t => t.toLowerCase().includes(query.toLowerCase())); const matchesAgent = !agent || m.agent === agent; return matchesQuery && matchesAgent; }); return { content: [{ type: "text", text: results.length === 0 ? "No memories found" : results.map(m => `[${m.timestamp}] ${m.content}`).join("\n\n") }] }; }
); // Tool: search
server.tool( "search", { tags: z.array(z.string()).describe("Tags to search for"), limit: z.number().optional().default(10) }, async ({ tags, limit }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const results = memories .filter(m => tags.some(t => m.tags.includes(t))) .slice(0, limit); return { content: [{ type: "text", text: results.map(m => `[${m.agent || "unknown"}] ${m.content}`).join("\n\n") }] }; }
); // Tool: rollback
server.tool( "rollback", { agent: z.string().describe("Agent name to rollback"), timestamp: z.string().describe("Rollback to this timestamp") }, async ({ agent, timestamp }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const rolledBack = memories.filter(m => m.agent !== agent || new Date(m.timestamp) <= new Date(timestamp) ); await fs.writeFile(MEMORY_FILE, JSON.stringify(rolledBack, null, 2)); return { content: [{ type: "text", text: `Rolled back ${agent} to ${timestamp}` }] }; }
); const transport = new StdioServerTransport();
await server.connect(transport);
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import fs from "fs/promises";
import path from "path"; const MEMORY_FILE = path.join(process.env.HOME, ".mcp-memory", "memories.json"); const server = new McpServer({ name: "memory", version: "1.0.0"
}); // Ensure memory file exists
async function initMemory() { await fs.mkdir(path.dirname(MEMORY_FILE), { recursive: true }); try { await fs.access(MEMORY_FILE); } catch { await fs.writeFile(MEMORY_FILE, JSON.stringify([])); }
} // Tool: remember
server.tool( "remember", { content: z.string().describe("Information to store"), tags: z.array(z.string()).describe("Tags for retrieval (e.g., ['backend', 'auth'])"), agent: z.string().optional().describe("Agent name for tagging") }, async ({ content, tags, agent }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const memory = { id: Date.now().toString(), content, tags, agent, timestamp: new Date().toISOString() }; memories.push(memory); await fs.writeFile(MEMORY_FILE, JSON.stringify(memories, null, 2)); return { content: [{ type: "text", text: `Stored memory with tags: ${tags.join(", ")}` }] }; }
); // Tool: recall
server.tool( "recall", { query: z.string().describe("Search query or tag to find"), agent: z.string().optional().describe("Filter by agent name") }, async ({ query, agent }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const results = memories.filter(m => { const matchesQuery = m.content.toLowerCase().includes(query.toLowerCase()) || m.tags.some(t => t.toLowerCase().includes(query.toLowerCase())); const matchesAgent = !agent || m.agent === agent; return matchesQuery && matchesAgent; }); return { content: [{ type: "text", text: results.length === 0 ? "No memories found" : results.map(m => `[${m.timestamp}] ${m.content}`).join("\n\n") }] }; }
); // Tool: search
server.tool( "search", { tags: z.array(z.string()).describe("Tags to search for"), limit: z.number().optional().default(10) }, async ({ tags, limit }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const results = memories .filter(m => tags.some(t => m.tags.includes(t))) .slice(0, limit); return { content: [{ type: "text", text: results.map(m => `[${m.agent || "unknown"}] ${m.content}`).join("\n\n") }] }; }
); // Tool: rollback
server.tool( "rollback", { agent: z.string().describe("Agent name to rollback"), timestamp: z.string().describe("Rollback to this timestamp") }, async ({ agent, timestamp }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const rolledBack = memories.filter(m => m.agent !== agent || new Date(m.timestamp) <= new Date(timestamp) ); await fs.writeFile(MEMORY_FILE, JSON.stringify(rolledBack, null, 2)); return { content: [{ type: "text", text: `Rolled back ${agent} to ${timestamp}` }] }; }
); const transport = new StdioServerTransport();
await server.connect(transport);
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import fs from "fs/promises";
import path from "path"; const MEMORY_FILE = path.join(process.env.HOME, ".mcp-memory", "memories.json"); const server = new McpServer({ name: "memory", version: "1.0.0"
}); // Ensure memory file exists
async function initMemory() { await fs.mkdir(path.dirname(MEMORY_FILE), { recursive: true }); try { await fs.access(MEMORY_FILE); } catch { await fs.writeFile(MEMORY_FILE, JSON.stringify([])); }
} // Tool: remember
server.tool( "remember", { content: z.string().describe("Information to store"), tags: z.array(z.string()).describe("Tags for retrieval (e.g., ['backend', 'auth'])"), agent: z.string().optional().describe("Agent name for tagging") }, async ({ content, tags, agent }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const memory = { id: Date.now().toString(), content, tags, agent, timestamp: new Date().toISOString() }; memories.push(memory); await fs.writeFile(MEMORY_FILE, JSON.stringify(memories, null, 2)); return { content: [{ type: "text", text: `Stored memory with tags: ${tags.join(", ")}` }] }; }
); // Tool: recall
server.tool( "recall", { query: z.string().describe("Search query or tag to find"), agent: z.string().optional().describe("Filter by agent name") }, async ({ query, agent }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const results = memories.filter(m => { const matchesQuery = m.content.toLowerCase().includes(query.toLowerCase()) || m.tags.some(t => t.toLowerCase().includes(query.toLowerCase())); const matchesAgent = !agent || m.agent === agent; return matchesQuery && matchesAgent; }); return { content: [{ type: "text", text: results.length === 0 ? "No memories found" : results.map(m => `[${m.timestamp}] ${m.content}`).join("\n\n") }] }; }
); // Tool: search
server.tool( "search", { tags: z.array(z.string()).describe("Tags to search for"), limit: z.number().optional().default(10) }, async ({ tags, limit }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const results = memories .filter(m => tags.some(t => m.tags.includes(t))) .slice(0, limit); return { content: [{ type: "text", text: results.map(m => `[${m.agent || "unknown"}] ${m.content}`).join("\n\n") }] }; }
); // Tool: rollback
server.tool( "rollback", { agent: z.string().describe("Agent name to rollback"), timestamp: z.string().describe("Rollback to this timestamp") }, async ({ agent, timestamp }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const rolledBack = memories.filter(m => m.agent !== agent || new Date(m.timestamp) <= new Date(timestamp) ); await fs.writeFile(MEMORY_FILE, JSON.stringify(rolledBack, null, 2)); return { content: [{ type: "text", text: `Rolled back ${agent} to ${timestamp}` }] }; }
); const transport = new StdioServerTransport();
await server.connect(transport);
node memory-server.js
node memory-server.js
node memory-server.js
Anda memiliki akses ke alat memori MCP: remember, recall, search, rollback. Ikuti protokol memori ini: **Saat Anda memulai sesi:**
1. Panggil kembali konteks: recall(query="ecommerce-api", agent="Backend Architect")
2. Tinjau item yang tertunda dari sesi terakhir **Saat Anda menyelesaikan pekerjaan:**
1. Ingat hasil kerja dengan tag: - remember(content="Membuat tabel pengguna dengan kunci utama UUID, hashing kata sandi bcrypt, otentikasi JWT dengan token refresh", tags=["ecommerce-api", "database", "auth"], agent="Backend Architect")
2. Sertakan keputusan yang dibuat dan item yang tertunda **Saat menyerahkan ke agen lain:**
1. Tinggalkan konteks untuk agen penerima: - remember(content="Endpoint API: /auth/login, /auth/register, /products, /orders. Alur otentikasi: token akses JWT (15menit) + token refresh (7 hari). Masalah yang diketahui: pembatasan _rate_ belum diimplementasikan", tags=["ecommerce-api", "handoff"], agent="Backend Architect", for="Frontend Developer") **Saat terjadi kegagalan:**
1. Cari status terakhir yang diketahui baik
2. Gunakan rollback untuk mengembalikan
Anda memiliki akses ke alat memori MCP: remember, recall, search, rollback. Ikuti protokol memori ini: **Saat Anda memulai sesi:**
1. Panggil kembali konteks: recall(query="ecommerce-api", agent="Backend Architect")
2. Tinjau item yang tertunda dari sesi terakhir **Saat Anda menyelesaikan pekerjaan:**
1. Ingat hasil kerja dengan tag: - remember(content="Membuat tabel pengguna dengan kunci utama UUID, hashing kata sandi bcrypt, otentikasi JWT dengan token refresh", tags=["ecommerce-api", "database", "auth"], agent="Backend Architect")
2. Sertakan keputusan yang dibuat dan item yang tertunda **Saat menyerahkan ke agen lain:**
1. Tinggalkan konteks untuk agen penerima: - remember(content="Endpoint API: /auth/login, /auth/register, /products, /orders. Alur otentikasi: token akses JWT (15menit) + token refresh (7 hari). Masalah yang diketahui: pembatasan _rate_ belum diimplementasikan", tags=["ecommerce-api", "handoff"], agent="Backend Architect", for="Frontend Developer") **Saat terjadi kegagalan:**
1. Cari status terakhir yang diketahui baik
2. Gunakan rollback untuk mengembalikan
Anda memiliki akses ke alat memori MCP: remember, recall, search, rollback. Ikuti protokol memori ini: **Saat Anda memulai sesi:**
1. Panggil kembali konteks: recall(query="ecommerce-api", agent="Backend Architect")
2. Tinjau item yang tertunda dari sesi terakhir **Saat Anda menyelesaikan pekerjaan:**
1. Ingat hasil kerja dengan tag: - remember(content="Membuat tabel pengguna dengan kunci utama UUID, hashing kata sandi bcrypt, otentikasi JWT dengan token refresh", tags=["ecommerce-api", "database", "auth"], agent="Backend Architect")
2. Sertakan keputusan yang dibuat dan item yang tertunda **Saat menyerahkan ke agen lain:**
1. Tinggalkan konteks untuk agen penerima: - remember(content="Endpoint API: /auth/login, /auth/register, /products, /orders. Alur otentikasi: token akses JWT (15menit) + token refresh (7 hari). Masalah yang diketahui: pembatasan _rate_ belum diimplementasikan", tags=["ecommerce-api", "handoff"], agent="Backend Architect", for="Frontend Developer") **Saat terjadi kegagalan:**
1. Cari status terakhir yang diketahui baik
2. Gunakan rollback untuk mengembalikan
Anda: "Aktifkan mode Backend Architect. Rancang sistem pengguna untuk API e-commerce kita." [Agen merancang sistem, membuat skema, mengimplementasikan otentikasi] Agen: "Sistem pengguna selesai. Menyimpan memori..."
→ Memanggil: remember("tabel pengguna dengan UUID, bcrypt, JWT + token refresh", tags: ["ecommerce-api", "auth", "database"]) [Sesi berakhir] [Keesokan harinya] Anda: "Lanjutkan dari kemarin" Agen: "Memanggil kembali konteks..."
→ Memanggil: recall(query="ecommerce-api")
→ Mengembalikan: "tabel pengguna dengan UUID, bcrypt, JWT + token refresh" Agen: "Kemarin saya merancang tabel pengguna dengan kunci utama UUID, mengimplementasikan hashing kata sandi bcrypt, dan menyiapkan otentikasi JWT dengan token refresh. Langkah selanjutnya: skema katalog produk. Siap untuk melanjutkan."
Anda: "Aktifkan mode Backend Architect. Rancang sistem pengguna untuk API e-commerce kita." [Agen merancang sistem, membuat skema, mengimplementasikan otentikasi] Agen: "Sistem pengguna selesai. Menyimpan memori..."
→ Memanggil: remember("tabel pengguna dengan UUID, bcrypt, JWT + token refresh", tags: ["ecommerce-api", "auth", "database"]) [Sesi berakhir] [Keesokan harinya] Anda: "Lanjutkan dari kemarin" Agen: "Memanggil kembali konteks..."
→ Memanggil: recall(query="ecommerce-api")
→ Mengembalikan: "tabel pengguna dengan UUID, bcrypt, JWT + token refresh" Agen: "Kemarin saya merancang tabel pengguna dengan kunci utama UUID, mengimplementasikan hashing kata sandi bcrypt, dan menyiapkan otentikasi JWT dengan token refresh. Langkah selanjutnya: skema katalog produk. Siap untuk melanjutkan."
Anda: "Aktifkan mode Backend Architect. Rancang sistem pengguna untuk API e-commerce kita." [Agen merancang sistem, membuat skema, mengimplementasikan otentikasi] Agen: "Sistem pengguna selesai. Menyimpan memori..."
→ Memanggil: remember("tabel pengguna dengan UUID, bcrypt, JWT + token refresh", tags: ["ecommerce-api", "auth", "database"]) [Sesi berakhir] [Keesokan harinya] Anda: "Lanjutkan dari kemarin" Agen: "Memanggil kembali konteks..."
→ Memanggil: recall(query="ecommerce-api")
→ Mengembalikan: "tabel pengguna dengan UUID, bcrypt, JWT + token refresh" Agen: "Kemarin saya merancang tabel pengguna dengan kunci utama UUID, mengimplementasikan hashing kata sandi bcrypt, dan menyiapkan otentikasi JWT dengan token refresh. Langkah selanjutnya: skema katalog produk. Siap untuk melanjutkan."
{ "mcpServers": { "memory": { "command": "node", "args": ["/absolute/path/to/memory-server.js"], "env": { "HOME": "/Users/your-username" } } }
}
{ "mcpServers": { "memory": { "command": "node", "args": ["/absolute/path/to/memory-server.js"], "env": { "HOME": "/Users/your-username" } } }
}
{ "mcpServers": { "memory": { "command": "node", "args": ["/absolute/path/to/memory-server.js"], "env": { "HOME": "/Users/your-username" } } }
}
Gunakan alat remember untuk menyimpan: "Test memory for ecommerce project"
Tags: ["test", "ecommerce-api"]
Gunakan alat remember untuk menyimpan: "Test memory for ecommerce project"
Tags: ["test", "ecommerce-api"]
Gunakan alat remember untuk menyimpan: "Test memory for ecommerce project"
Tags: ["test", "ecommerce-api"]
Gunakan alat recall untuk menemukan memori tentang "test"
Gunakan alat recall untuk menemukan memori tentang "test"
Gunakan alat recall untuk menemukan memori tentang "test"
{ "mcpServers": { "memory": { "command": "node", "args": ["/absolute/path/to/memory-server.js"] } }
}
{ "mcpServers": { "memory": { "command": "node", "args": ["/absolute/path/to/memory-server.js"] } }
}
{ "mcpServers": { "memory": { "command": "node", "args": ["/absolute/path/to/memory-server.js"] } }
}
@memory remember "Memulai proyek API e-commerce dengan PostgreSQL"
Tags: ["ecommerce-api", "setup"]
@memory remember "Memulai proyek API e-commerce dengan PostgreSQL"
Tags: ["ecommerce-api", "setup"]
@memory remember "Memulai proyek API e-commerce dengan PostgreSQL"
Tags: ["ecommerce-api", "setup"]
@memory recall query="ecommerce"
@memory recall query="ecommerce"
@memory recall query="ecommerce"
remember({ content: "Memilih PostgreSQL daripada MySQL karena: (1) dukungan JSONB untuk atribut produk yang fleksibel, (2) pencarian teks penuh yang lebih baik, (3) dukungan asli UUID", tags: ["ecommerce-api", "database", "decision"], agent: "Backend Architect"
})
remember({ content: "Memilih PostgreSQL daripada MySQL karena: (1) dukungan JSONB untuk atribut produk yang fleksibel, (2) pencarian teks penuh yang lebih baik, (3) dukungan asli UUID", tags: ["ecommerce-api", "database", "decision"], agent: "Backend Architect"
})
remember({ content: "Memilih PostgreSQL daripada MySQL karena: (1) dukungan JSONB untuk atribut produk yang fleksibel, (2) pencarian teks penuh yang lebih baik, (3) dukungan asli UUID", tags: ["ecommerce-api", "database", "decision"], agent: "Backend Architect"
})
recall(query="PostgreSQL MySQL decision")
recall(query="PostgreSQL MySQL decision")
recall(query="PostgreSQL MySQL decision")
remember({ content: "Backend selesai. Endpoint: POST /auth/login, POST /auth/register, GET /products, POST /orders. Otentikasi: akses JWT 15 menit + refresh 7 hari. Tertunda: pembatasan rate, verifikasi email. Kebutuhan frontend: form login, daftar produk, keranjang, checkout.", tags: ["ecommerce-api", "handoff", "backend-complete"], agent: "Backend Architect", for: "Frontend Developer"
})
remember({ content: "Backend selesai. Endpoint: POST /auth/login, POST /auth/register, GET /products, POST /orders. Otentikasi: akses JWT 15 menit + refresh 7 hari. Tertunda: pembatasan rate, verifikasi email. Kebutuhan frontend: form login, daftar produk, keranjang, checkout.", tags: ["ecommerce-api", "handoff", "backend-complete"], agent: "Backend Architect", for: "Frontend Developer"
})
remember({ content: "Backend selesai. Endpoint: POST /auth/login, POST /auth/register, GET /products, POST /orders. Otentikasi: akses JWT 15 menit + refresh 7 hari. Tertunda: pembatasan rate, verifikasi email. Kebutuhan frontend: form login, daftar produk, keranjang, checkout.", tags: ["ecommerce-api", "handoff", "backend-complete"], agent: "Backend Architect", for: "Frontend Developer"
})
recall(query="handoff", agent="Backend Architect")
recall(query="handoff", agent="Backend Architect")
recall(query="handoff", agent="Backend Architect")
remember({ content: "Sesi selesai. Selesai: tabel pengguna, endpoint otentikasi, skema produk. Sesi berikutnya: sistem pesanan, webhook pembayaran. Penghambat: menunggu kunci API Stripe.", tags: ["ecommerce-api", "checkpoint", "session-1"], agent: "Backend Architect"
})
remember({ content: "Sesi selesai. Selesai: tabel pengguna, endpoint otentikasi, skema produk. Sesi berikutnya: sistem pesanan, webhook pembayaran. Penghambat: menunggu kunci API Stripe.", tags: ["ecommerce-api", "checkpoint", "session-1"], agent: "Backend Architect"
})
remember({ content: "Sesi selesai. Selesai: tabel pengguna, endpoint otentikasi, skema produk. Sesi berikutnya: sistem pesanan, webhook pembayaran. Penghambat: menunggu kunci API Stripe.", tags: ["ecommerce-api", "checkpoint", "session-1"], agent: "Backend Architect"
})
recall(query="checkpoint session-1")
recall(query="checkpoint session-1")
recall(query="checkpoint session-1")
remember({ content: "BUG: Token refresh tidak kedaluwarsa setelah logout. Token disimpan di memori, tidak persisten. Perbaikan: pindahkan ke Redis dengan TTL.", tags: ["ecommerce-api", "bug", "auth"], agent: "Code Reviewer", severity: "high"
})
remember({ content: "BUG: Token refresh tidak kedaluwarsa setelah logout. Token disimpan di memori, tidak persisten. Perbaikan: pindahkan ke Redis dengan TTL.", tags: ["ecommerce-api", "bug", "auth"], agent: "Code Reviewer", severity: "high"
})
remember({ content: "BUG: Token refresh tidak kedaluwarsa setelah logout. Token disimpan di memori, tidak persisten. Perbaikan: pindahkan ke Redis dengan TTL.", tags: ["ecommerce-api", "bug", "auth"], agent: "Code Reviewer", severity: "high"
})
search(tags=["bug", "ecommerce-api"])
search(tags=["bug", "ecommerce-api"])
search(tags=["bug", "ecommerce-api"])
import crypto from 'crypto'; const ENCRYPTION_KEY = process.env.MEMORY_ENCRYPTION_KEY;
const ALGORITHM = 'aes-256-gcm'; function encrypt(text) { const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv(ALGORITHM, Buffer.from(ENCRYPTION_KEY), iv); const encrypted = cipher.update(text, 'utf8', 'hex'); return { encryptedData: encrypted + cipher.final('hex'), iv: iv.toString('hex'), authTag: cipher.getAuthTag().toString('hex') };
} function decrypt(encrypted) { const decipher = crypto.createDecipheriv( ALGORITHM, Buffer.from(ENCRYPTION_KEY), Buffer.from(encrypted.iv, 'hex') ); decipher.setAuthTag(Buffer.from(encrypted.authTag, 'hex')); return decipher.update(encrypted.encryptedData, 'hex', 'utf8') + decipher.final('utf8');
}
import crypto from 'crypto'; const ENCRYPTION_KEY = process.env.MEMORY_ENCRYPTION_KEY;
const ALGORITHM = 'aes-256-gcm'; function encrypt(text) { const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv(ALGORITHM, Buffer.from(ENCRYPTION_KEY), iv); const encrypted = cipher.update(text, 'utf8', 'hex'); return { encryptedData: encrypted + cipher.final('hex'), iv: iv.toString('hex'), authTag: cipher.getAuthTag().toString('hex') };
} function decrypt(encrypted) { const decipher = crypto.createDecipheriv( ALGORITHM, Buffer.from(ENCRYPTION_KEY), Buffer.from(encrypted.iv, 'hex') ); decipher.setAuthTag(Buffer.from(encrypted.authTag, 'hex')); return decipher.update(encrypted.encryptedData, 'hex', 'utf8') + decipher.final('utf8');
}
import crypto from 'crypto'; const ENCRYPTION_KEY = process.env.MEMORY_ENCRYPTION_KEY;
const ALGORITHM = 'aes-256-gcm'; function encrypt(text) { const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv(ALGORITHM, Buffer.from(ENCRYPTION_KEY), iv); const encrypted = cipher.update(text, 'utf8', 'hex'); return { encryptedData: encrypted + cipher.final('hex'), iv: iv.toString('hex'), authTag: cipher.getAuthTag().toString('hex') };
} function decrypt(encrypted) { const decipher = crypto.createDecipheriv( ALGORITHM, Buffer.from(ENCRYPTION_KEY), Buffer.from(encrypted.iv, 'hex') ); decipher.setAuthTag(Buffer.from(encrypted.authTag, 'hex')); return decipher.update(encrypted.encryptedData, 'hex', 'utf8') + decipher.final('utf8');
} - Siapkan server memori MCP dengan alat remember, recall, search, dan rollback.
- Tambahkan instruksi memori ke prompt agen.
- Konfigurasi ~/.claude/settings.json untuk Claude Code atau .cursor/mcp.json untuk Cursor.
- Gunakan pola memori untuk pencatatan keputusan, serah terima agen, dan titik periksa sesi. Agen mempertahankan konteks lintas sesi—tidak perlu lagi menyalin-tempel percakapan sebelumnya. - Pastikan jalur file memori (~/.mcp-memory/memories.json) benar
- Server MCP berjalan
- Konfigurasi Claude Code/Cursor sudah benar - Gunakan tag yang lebih spesifik
- Filter berdasarkan nama agen
- Pakai frasa persis dalam tanda kutip - Arsipkan memori lama
- Gunakan rollback untuk membersihkan proyek selesai
- Tambahkan tanggal kedaluwarsa ke skema memori - Tambahkan pencarian semantik dengan embeddings
- Implementasikan auto-archive setelah 30 hari
- Tambahkan ringkasan memori (summarize session) - Bagikan server memori pusat ke seluruh tim
- Tag memori berdasarkan proyek/pengembang
- Buat alur onboarding anggota baru - Catat otomatis commit git sebagai memori
- Sinkron dengan Jira/Linear
- Ekspor memori ke dokumentasi - Pastikan server MCP berjalan sebelum Claude Code
- Verifikasi file memori: ls -la ~/.mcp-memory/memories.json
- Pastikan izin file: chmod 644 ~/.mcp-memory/memories.json
- Konfirmasi konfigurasi server di ~/.claude/settings.json - Verifikasi query cocok dengan tag (case sensitive)
- Coba istilah pencarian lebih luas atau gunakan search
- Pastikan memori benar-benar disimpan: cat ~/.mcp-memory/memories.json
- Gunakan filter agent jika perlu - Implementasikan auto-archive > 30 hari
- Tambahkan alat prune untuk hapus memori berdasarkan tanggal
- Pisahkan file memori per proyek/tanggal
- Gunakan backend database (SQLite) untuk skala besar - Periksa versi Node.js: node --version (minimal 18)
- Instal dependensi: npm install @modelcontextprotocol/sdk zod
- Periksa kesalahan sintaks kode server
- Jalankan langsung untuk debugging: node memory-server.js - Selalu sertakan field agent saat remember
- Gunakan tag unik: ["project-x", "backend", "auth"]
- Filter recall berdasarkan agent
- Pertimbangkan file memori terpisah per proyek - Wajibkan kunci API pada setiap panggilan alat memori
- Implementasikan namespace memori per user
- Logging semua operasi memori untuk audit trail
- Batasi rate request per pengguna