Tools: Cách Thêm Bộ Nhớ Vĩnh Viễn Cho AI Agent (Để Nhớ Được Hôm Qua)

Tools: Cách Thêm Bộ Nhớ Vĩnh Viễn Cho AI Agent (Để Nhớ Được Hôm Qua)

TÓM TẮT

Bộ nhớ MCP là gì?

Bước 1: Thiết lập Máy chủ Bộ nhớ MCP

Bước 2: Thêm Hướng dẫn Bộ nhớ vào Agent

Bước 3: Cấu hình cho Claude Code

Bước 4: Cấu hình cho Cursor

Các Mẫu Bộ nhớ cho Luồng Công việc Thực tế

Mẫu 1: Ghi nhật ký Quyết định

Mẫu 2: Chuyển giao Tác nhân

Mẫu 3: Điểm kiểm soát Phiên

Mẫu 4: Theo dõi Lỗi

Khắc phục sự cố

Những Gì Bạn Đã Xây Dựng

Các Bước Tiếp theo

Khắc phục các Sự cố Thường gặp

Các Vấn đề Bảo mật của Máy chủ Bộ nhớ

Câu hỏi thường gặp Thêm bộ nhớ bền vững cho các tác nhân AI qua 4 bước thực tế: (1) Thiết lập máy chủ bộ nhớ MCP với các công cụ remember, recall, search, rollback, (2) Thêm hướng dẫn bộ nhớ vào prompt của tác nhân AI, (3) Cấu hình file ~/.claude/settings.json cho Claude Code hoặc .cursor/mcp.json cho Cursor, (4) Sử dụng các mẫu bộ nhớ để ghi nhật ký quyết định, chuyển giao tác nhân và checkpoint phiên. Các tác nhân giữ ngữ cảnh xuyên phiên — không cần copy-paste hội thoại cũ. Dùng thử Apidog ngay hôm nay Giải quyết triệt để vấn đề “Tôi không nhớ ngày hôm qua”. Bằng giao thức MCP, tác nhân AI ghi nhớ các quyết định, bàn giao và ngữ cảnh xuyên suốt các phiên làm việc. Bạn thường gặp quy trình này: Bạn copy-paste hội thoại cũ. Tác nhân phải đọc lại 2000 dòng ngữ cảnh. Mất 15 phút để đồng bộ. Bộ nhớ bền vững loại bỏ bước này. Với MCP, tác nhân tự động lưu trữ và truy xuất quyết định. Không copy-paste, không giải thích lại. Trong hướng dẫn này, bạn sẽ thiết lập bộ nhớ MCP cho AI agent. Bạn sẽ học cách lưu quyết định từ các phiên Kiến trúc sư Backend, thu hồi ngữ cảnh khi chuyển sang tối ưu hóa CSDL, chuyển giao sản phẩm cho Frontend Dev — tất cả mà không mất ngữ cảnh. Mẫu bộ nhớ này áp dụng cho cả workflow xây dựng API tích hợp với Apidog hoặc các sprint dài ngày. Bộ nhớ MCP cho phép AI agent lưu trữ và truy xuất thông tin xuyên phiên. Hình dung như một cuốn sổ ghi chú chung cho mọi agent. Bốn công cụ chính của bộ nhớ MCP: Bạn cần một MCP memory server cung cấp các công cụ bộ nhớ. Có hai lựa chọn: A. Sử dụng máy chủ bộ nhớ đã deploy B. Tự chạy một máy chủ cục bộ đơn giản Tạo file memory-server.js: Không cần sửa code agent. Chỉ cần bổ sung prompt hướng dẫn sử dụng MCP tools: Thêm MCP server vào ~/.claude/settings.json: Khởi động lại Claude Code. Đảm bảo các công cụ bộ nhớ đã sẵn sàng. Tạo file .cursor/mcp.json trong thư mục dự án: Ghi lại mỗi quyết định kỹ thuật: Sau này tra cứu lý do: Chuyển giao ngữ cảnh khi đổi agent: Agent mới bắt đầu với: Cuối mỗi phiên làm việc: Ghi lại bug phát hiện: Bộ nhớ không bền vững: Quá nhiều kết quả khi thu hồi: Tệp bộ nhớ ngày càng lớn: Mở rộng máy chủ bộ nhớ: Tích hợp với công cụ khác: Bộ nhớ không bền vững giữa các phiên: Server không khởi động: Nhiều agent ghi đè memory của nhau: Lưu trữ Khóa API: Nếu lưu dữ liệu nhạy cảm (API key, password), hãy mã hóa: Các AI agent của bạn giờ đã có bộ nhớ bền vững. Chúng nhớ hôm qua, thu hồi quyết định, chuyển giao ngữ cảnh mà không copy-paste. Không còn “Tôi không có ngữ cảnh từ các phiên trước nữa.” Không còn giải thích lại. Không còn lãng phí thời gian. Đó là sức mạnh của MCP: cho agent một cuốn sổ ghi chú chung, giúp chúng thật sự hữu ích cho dự án nhiều ngày. Bộ nhớ MCP là gì?

Một giao thức cho phép AI agent lưu và truy xuất thông tin xuyên phiên, giống như một cuốn sổ ghi chú chung duy trì ngữ cảnh ngoài từng hội thoại. Làm sao thiết lập bộ nhớ bền vững cho Claude Code?Cài MCP memory server, thêm vào ~/.claude/settings.json với lệnh và path server. Khởi động lại Claude Code, các tool (remember, recall, search, rollback) sẽ xuất hiện. Tác nhân AI nào hỗ trợ MCP?Bất kỳ agent chạy trên client hỗ trợ MCP (Claude Code, Cursor, Windsurf...) đều dùng được memory tools. Không cần sửa code agent, chỉ cần bổ sung hướng dẫn vào prompt. Mẫu bộ nhớ tốt nhất cho handoff?Dùng remember với tag như ["handoff", "project-name"] để lưu context cho agent tiếp theo. Bao gồm việc đã xong, task pending, issues. Agent nhận dùng recall(query="handoff") để lấy lại. Server MCP lưu được bao nhiêu memory?Tùy implementation. Server mẫu dùng JSON file, phình to vô hạn. Server production nên có policy hết hạn, auto archive, hoặc backend CSDL cho quy mô lớn. Team có thể dùng chung một memory server?Có. Chạy server trên máy chủ chung hoặc cloud, cấu hình client của team member trỏ về, tag memory theo project/dev để truy xuất dễ dàng. Recall trả về quá nhiều kết quả?

Lưu memory với tag chi tiết hơn. Lọc theo agent khi recall. Dùng cụm từ chính xác trong dấu ngoặc kép. Có thể triển khai semantic search với embedding cho truy xuất thông minh hơn. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Code Block

Copy

Ngày 1: "Xây dựng hệ thống xác thực người dùng" Tác nhân: [Xây dựng xác thực JWT, tạo bảng người dùng, triển khai mã thông báo làm mới] Ngày 2: "Tiếp tục từ ngày hôm qua" Tác nhân: "Tôi không có ngữ cảnh từ các phiên trước đó. Bạn có thể dán những gì chúng ta đã làm không?" Ngày 1: "Xây dựng hệ thống xác thực người dùng" Tác nhân: [Xây dựng xác thực JWT, tạo bảng người dùng, triển khai mã thông báo làm mới] Ngày 2: "Tiếp tục từ ngày hôm qua" Tác nhân: "Tôi không có ngữ cảnh từ các phiên trước đó. Bạn có thể dán những gì chúng ta đã làm không?" Ngày 1: "Xây dựng hệ thống xác thực người dùng" Tác nhân: [Xây dựng xác thực JWT, tạo bảng người dùng, triển khai mã thông báo làm mới] Ngày 2: "Tiếp tục từ ngày hôm qua" Tác nhân: "Tôi không có ngữ cảnh từ các phiên trước đó. Bạn có thể dán những gì chúng ta đã làm không?" ┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐ │ Tác nhân AI │ │ Máy chủ bộ nhớ │ │ Lưu trữ │ │ (Claude Code) │◄───────►│ MCP │◄───────►│ (SQLite) │ └─────────────────┘ JSON └──────────────────┘ I/O └─────────────┘ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐ │ Tác nhân AI │ │ Máy chủ bộ nhớ │ │ Lưu trữ │ │ (Claude Code) │◄───────►│ MCP │◄───────►│ (SQLite) │ └─────────────────┘ JSON └──────────────────┘ I/O └─────────────┘ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐ │ Tác nhân AI │ │ Máy chủ bộ nhớ │ │ Lưu trữ │ │ (Claude Code) │◄───────►│ MCP │◄───────►│ (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("Thông tin cần lưu trữ"), tags: z.array(z.string()).describe("Thẻ để truy xuất (ví dụ: ['backend', 'auth'])"), agent: z.string().optional().describe("Tên tác nhân để gắn thẻ") }, 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: `Đã lưu bộ nhớ với các thẻ: ${tags.join(", ")}` }] }; } ); // Tool: recall server.tool( "recall", { query: z.string().describe("Truy vấn tìm kiếm hoặc thẻ để tìm"), agent: z.string().optional().describe("Lọc theo tên tác nhân") }, async ({ query, agent }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const results = memories.filter(m => (m.content.toLowerCase().includes(query.toLowerCase()) || m.tags.some(t => t.toLowerCase().includes(query.toLowerCase()))) && (!agent || m.agent === agent) ); return { content: [{ type: "text", text: results.length === 0 ? "Không tìm thấy bộ nhớ nào" : results.map(m => `[${m.timestamp}] ${m.content}`).join("\n\n") }] }; } ); // Tool: search server.tool( "search", { tags: z.array(z.string()).describe("Các thẻ cần tìm kiếm"), 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("Tên tác nhân để khôi phục"), timestamp: z.string().describe("Khôi phục về thời điểm này") }, 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: `Đã khôi phục ${agent} về ${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("Thông tin cần lưu trữ"), tags: z.array(z.string()).describe("Thẻ để truy xuất (ví dụ: ['backend', 'auth'])"), agent: z.string().optional().describe("Tên tác nhân để gắn thẻ") }, 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: `Đã lưu bộ nhớ với các thẻ: ${tags.join(", ")}` }] }; } ); // Tool: recall server.tool( "recall", { query: z.string().describe("Truy vấn tìm kiếm hoặc thẻ để tìm"), agent: z.string().optional().describe("Lọc theo tên tác nhân") }, async ({ query, agent }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const results = memories.filter(m => (m.content.toLowerCase().includes(query.toLowerCase()) || m.tags.some(t => t.toLowerCase().includes(query.toLowerCase()))) && (!agent || m.agent === agent) ); return { content: [{ type: "text", text: results.length === 0 ? "Không tìm thấy bộ nhớ nào" : results.map(m => `[${m.timestamp}] ${m.content}`).join("\n\n") }] }; } ); // Tool: search server.tool( "search", { tags: z.array(z.string()).describe("Các thẻ cần tìm kiếm"), 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("Tên tác nhân để khôi phục"), timestamp: z.string().describe("Khôi phục về thời điểm này") }, 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: `Đã khôi phục ${agent} về ${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("Thông tin cần lưu trữ"), tags: z.array(z.string()).describe("Thẻ để truy xuất (ví dụ: ['backend', 'auth'])"), agent: z.string().optional().describe("Tên tác nhân để gắn thẻ") }, 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: `Đã lưu bộ nhớ với các thẻ: ${tags.join(", ")}` }] }; } ); // Tool: recall server.tool( "recall", { query: z.string().describe("Truy vấn tìm kiếm hoặc thẻ để tìm"), agent: z.string().optional().describe("Lọc theo tên tác nhân") }, async ({ query, agent }) => { await initMemory(); const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8")); const results = memories.filter(m => (m.content.toLowerCase().includes(query.toLowerCase()) || m.tags.some(t => t.toLowerCase().includes(query.toLowerCase()))) && (!agent || m.agent === agent) ); return { content: [{ type: "text", text: results.length === 0 ? "Không tìm thấy bộ nhớ nào" : results.map(m => `[${m.timestamp}] ${m.content}`).join("\n\n") }] }; } ); // Tool: search server.tool( "search", { tags: z.array(z.string()).describe("Các thẻ cần tìm kiếm"), 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("Tên tác nhân để khôi phục"), timestamp: z.string().describe("Khôi phục về thời điểm này") }, 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: `Đã khôi phục ${agent} về ${timestamp}` }] }; } ); const transport = new StdioServerTransport(); await server.connect(transport); node memory-server.js node memory-server.js node memory-server.js Bạn có quyền truy cập vào các công cụ bộ nhớ MCP: remember, recall, search, rollback. Tuân thủ các quy tắc sau: **Khi bắt đầu một phiên:** 1. recall(query="ecommerce-api", agent="Backend Architect") 2. Xem lại các item pending từ phiên trước **Khi hoàn thành công việc:** 1. remember(content="Đã tạo bảng người dùng với UUID...", tags=["ecommerce-api", "database", "auth"], agent="Backend Architect") 2. Lưu lại quyết định, các mục pending **Khi chuyển giao cho agent khác:** 1. remember(content="Điểm cuối API: ...", tags=["ecommerce-api", "handoff"], agent="Backend Architect", for="Frontend Developer") **Khi có lỗi:** 1. recall/search checkpoint gần nhất 2. rollback về trạng thái ổn định Bạn có quyền truy cập vào các công cụ bộ nhớ MCP: remember, recall, search, rollback. Tuân thủ các quy tắc sau: **Khi bắt đầu một phiên:** 1. recall(query="ecommerce-api", agent="Backend Architect") 2. Xem lại các item pending từ phiên trước **Khi hoàn thành công việc:** 1. remember(content="Đã tạo bảng người dùng với UUID...", tags=["ecommerce-api", "database", "auth"], agent="Backend Architect") 2. Lưu lại quyết định, các mục pending **Khi chuyển giao cho agent khác:** 1. remember(content="Điểm cuối API: ...", tags=["ecommerce-api", "handoff"], agent="Backend Architect", for="Frontend Developer") **Khi có lỗi:** 1. recall/search checkpoint gần nhất 2. rollback về trạng thái ổn định Bạn có quyền truy cập vào các công cụ bộ nhớ MCP: remember, recall, search, rollback. Tuân thủ các quy tắc sau: **Khi bắt đầu một phiên:** 1. recall(query="ecommerce-api", agent="Backend Architect") 2. Xem lại các item pending từ phiên trước **Khi hoàn thành công việc:** 1. remember(content="Đã tạo bảng người dùng với UUID...", tags=["ecommerce-api", "database", "auth"], agent="Backend Architect") 2. Lưu lại quyết định, các mục pending **Khi chuyển giao cho agent khác:** 1. remember(content="Điểm cuối API: ...", tags=["ecommerce-api", "handoff"], agent="Backend Architect", for="Frontend Developer") **Khi có lỗi:** 1. recall/search checkpoint gần nhất 2. rollback về trạng thái ổn định Bạn: "Kích hoạt chế độ Kiến trúc sư Backend. Thiết kế hệ thống người dùng cho API thương mại điện tử." [Tác nhân thiết kế, tạo lược đồ, triển khai xác thực] Tác nhân: "Hệ thống người dùng hoàn tất. Đang lưu bộ nhớ..." → remember("bảng người dùng với UUID, bcrypt, JWT + mã thông báo làm mới", tags: ["ecommerce-api", "auth", "database"]) [Kết thúc phiên] [Ngày hôm sau] Bạn: "Tiếp tục từ ngày hôm qua" Tác nhân: "Đang thu hồi ngữ cảnh..." → recall(query="ecommerce-api") → Trả về: "bảng người dùng với UUID, bcrypt, JWT + mã thông báo làm mới" Tác nhân: "Hôm qua tôi đã thiết kế bảng người dùng với UUID, bcrypt, JWT... Bước tiếp: lược đồ danh mục sản phẩm." Bạn: "Kích hoạt chế độ Kiến trúc sư Backend. Thiết kế hệ thống người dùng cho API thương mại điện tử." [Tác nhân thiết kế, tạo lược đồ, triển khai xác thực] Tác nhân: "Hệ thống người dùng hoàn tất. Đang lưu bộ nhớ..." → remember("bảng người dùng với UUID, bcrypt, JWT + mã thông báo làm mới", tags: ["ecommerce-api", "auth", "database"]) [Kết thúc phiên] [Ngày hôm sau] Bạn: "Tiếp tục từ ngày hôm qua" Tác nhân: "Đang thu hồi ngữ cảnh..." → recall(query="ecommerce-api") → Trả về: "bảng người dùng với UUID, bcrypt, JWT + mã thông báo làm mới" Tác nhân: "Hôm qua tôi đã thiết kế bảng người dùng với UUID, bcrypt, JWT... Bước tiếp: lược đồ danh mục sản phẩm." Bạn: "Kích hoạt chế độ Kiến trúc sư Backend. Thiết kế hệ thống người dùng cho API thương mại điện tử." [Tác nhân thiết kế, tạo lược đồ, triển khai xác thực] Tác nhân: "Hệ thống người dùng hoàn tất. Đang lưu bộ nhớ..." → remember("bảng người dùng với UUID, bcrypt, JWT + mã thông báo làm mới", tags: ["ecommerce-api", "auth", "database"]) [Kết thúc phiên] [Ngày hôm sau] Bạn: "Tiếp tục từ ngày hôm qua" Tác nhân: "Đang thu hồi ngữ cảnh..." → recall(query="ecommerce-api") → Trả về: "bảng người dùng với UUID, bcrypt, JWT + mã thông báo làm mới" Tác nhân: "Hôm qua tôi đã thiết kế bảng người dùng với UUID, bcrypt, JWT... Bước tiếp: lược đồ danh mục sản phẩm." { "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" } } } } remember "Bộ nhớ thử nghiệm cho dự án thương mại điện tử" Thẻ: ["test", "ecommerce-api"] remember "Bộ nhớ thử nghiệm cho dự án thương mại điện tử" Thẻ: ["test", "ecommerce-api"] remember "Bộ nhớ thử nghiệm cho dự án thương mại điện tử" Thẻ: ["test", "ecommerce-api"] recall "test" recall "test" recall "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 "Bắt đầu dự án API thương mại điện tử với PostgreSQL" Thẻ: ["ecommerce-api", "setup"] @memory remember "Bắt đầu dự án API thương mại điện tử với PostgreSQL" Thẻ: ["ecommerce-api", "setup"] @memory remember "Bắt đầu dự án API thương mại điện tử với PostgreSQL" Thẻ: ["ecommerce-api", "setup"] @memory recall query="ecommerce" @memory recall query="ecommerce" @memory recall query="ecommerce" remember({ content: "Chọn PostgreSQL thay vì MySQL vì: (1) hỗ trợ JSONB, (2) tìm kiếm toàn văn tốt hơn, (3) hỗ trợ UUID gốc", tags: ["ecommerce-api", "database", "decision"], agent: "Backend Architect" }) remember({ content: "Chọn PostgreSQL thay vì MySQL vì: (1) hỗ trợ JSONB, (2) tìm kiếm toàn văn tốt hơn, (3) hỗ trợ UUID gốc", tags: ["ecommerce-api", "database", "decision"], agent: "Backend Architect" }) remember({ content: "Chọn PostgreSQL thay vì MySQL vì: (1) hỗ trợ JSONB, (2) tìm kiếm toàn văn tốt hơn, (3) hỗ trợ UUID gốc", tags: ["ecommerce-api", "database", "decision"], agent: "Backend Architect" }) recall(query="quyết định PostgreSQL MySQL") recall(query="quyết định PostgreSQL MySQL") recall(query="quyết định PostgreSQL MySQL") remember({ content: "Backend hoàn tất. Điểm cuối: POST /auth/login, ...", tags: ["ecommerce-api", "handoff", "backend-complete"], agent: "Backend Architect", for: "Frontend Developer" }) remember({ content: "Backend hoàn tất. Điểm cuối: POST /auth/login, ...", tags: ["ecommerce-api", "handoff", "backend-complete"], agent: "Backend Architect", for: "Frontend Developer" }) remember({ content: "Backend hoàn tất. Điểm cuối: POST /auth/login, ...", 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: "Phiên hoàn tất. Đã xong: bảng người dùng, điểm cuối xác thực, lược đồ sản phẩm. Phiên tiếp theo: hệ thống đặt hàng...", tags: ["ecommerce-api", "checkpoint", "session-1"], agent: "Backend Architect" }) remember({ content: "Phiên hoàn tất. Đã xong: bảng người dùng, điểm cuối xác thực, lược đồ sản phẩm. Phiên tiếp theo: hệ thống đặt hàng...", tags: ["ecommerce-api", "checkpoint", "session-1"], agent: "Backend Architect" }) remember({ content: "Phiên hoàn tất. Đã xong: bảng người dùng, điểm cuối xác thực, lược đồ sản phẩm. Phiên tiếp theo: hệ thống đặt hàng...", 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: "LỖI: Mã thông báo làm mới không hết hạn sau khi đăng xuất. Khắc phục: chuyển sang Redis với TTL.", tags: ["ecommerce-api", "bug", "auth"], agent: "Code Reviewer", severity: "high" }) remember({ content: "LỖI: Mã thông báo làm mới không hết hạn sau khi đăng xuất. Khắc phục: chuyển sang Redis với TTL.", tags: ["ecommerce-api", "bug", "auth"], agent: "Code Reviewer", severity: "high" }) remember({ content: "LỖI: Mã thông báo làm mới không hết hạn sau khi đăng xuất. Khắc phục: chuyển sang Redis với 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'); } - Kiểm tra file bộ nhớ (~/.mcp-memory/memories.json) - Đảm bảo MCP server đang chạy - Xác minh cấu hình MCP cho Claude Code/Cursor - Sử dụng thẻ chi tiết hơn - Lọc theo tên agent - Dùng cụm từ chính xác trong dấu ngoặc kép - Định kỳ lưu trữ bộ nhớ cũ - Dùng rollback để dọn các dự án đã xong - Thêm ngày hết hạn vào schema bộ nhớ - Thêm semantic search với embeddings - Triển khai hết hạn bộ nhớ tự động (ví dụ: 30 ngày) - Thêm tóm tắt bộ nhớ cho các phiên dài - Dùng chung một memory server cho cả team - Gắn thẻ bộ nhớ theo dự án và developer - Tạo quy trình onboarding cho thành viên mới - Tự động ghi nhật ký commit git thành memory - Đồng bộ hóa với quản lý dự án (Jira, Linear) - Xuất memory ra tài liệu - Đảm bảo MCP server chạy trước khi mở Claude Code - Kiểm tra file: ls -la ~/.mcp-memory/memories.json - Chỉnh quyền: chmod 644 ~/.mcp-memory/memories.json - Kiểm tra cấu hình server trong ~/.claude/settings.json - Kiểm tra truy vấn đúng thẻ (có phân biệt chữ hoa/thường) - Thử search rộng hơn hoặc search với thẻ cụ thể - Kiểm tra file memory đã lưu: cat ~/.mcp-memory/memories.json - Đảm bảo filter agent đúng (nếu có) - Tự động lưu trữ memory >30 ngày - Thêm tool prune xóa theo ngày - Chia nhỏ file theo project/ngày - Dùng backend SQLite thay cho JSON nếu quy mô lớn - Kiểm tra Node.js: node --version (>=18) - Cài đủ package: npm install @modelcontextprotocol/sdk zod - Sửa lỗi syntax nếu có - Chạy trực tiếp xem log: node memory-server.js - Luôn truyền trường agent khi remember - Dùng thẻ đặc trưng cho từng project: ["project-x", "backend"] - Lọc recall theo agent - Cân nhắc file memory riêng cho từng project - Yêu cầu API key cho mỗi request - Triển khai namespace memory cho từng user - Ghi log mọi thao tác để audit - Giới hạn tốc độ theo user