Skip to main content
Glama
README.md
# Memory MCP (local-first)

## Yêu cầu

- Node.js >= 20
- Docker + Docker Compose

## Docker (phiên bản image)

- Postgres: `postgres:16-alpine`
- Qdrant: `qdrant/qdrant:v1.9.3`

## Checklist khởi động

1. `docker compose up -d`
2. `npm install`
3. Copy `.env.example` → `.env` (Postgres host mặc định **`127.0.0.1:55432`**)
4. `npm run db:migrate`
5. `npm run qdrant:bootstrap`
6. `npm run dev` hoặc `npm run build && npm start`

## Scripts

| Script | Mô tả |
|--------|--------|
| `npm run dev` | MCP server (tsx watch, stdio) |
| `npm run build` | `tsc` → `dist/` |
| `npm start` | `node dist/index.js` |
| `npm test` | Vitest: unit + integration (xem bên dưới) |
| `npm run db:migrate` | Chạy migration Postgres theo thứ tự (`0001_init`, `0002_phase2_indexes`, …) |
| `npm run qdrant:bootstrap` | Tạo collection Qdrant nếu chưa có |

## ENV

Copy `.env.example` thành `.env`.

| Biến | Ý nghĩa |
|------|---------|
| `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD`, `PGDATABASE` | Kết nối Postgres (`PGPORT=55432` khi dùng compose như mặc định repo) |
| `QDRANT_URL` | REST API Qdrant (mặc định `http://localhost:6333`) |
| `QDRANT_COLLECTION` | Tên collection điểm vector |
| `EMBEDDING_PROVIDER` | Phase 0–1: `hash` (embedding offline) |
| `EMBEDDING_DIMENSION` | Chiều vector (mặc định `384`) |
| `LOG_LEVEL` | Mức log pino |
| `MCP_ACTOR` | Actor mặc định cho audit (optional) |

## MCP tools (stdio)

Server giao tiếp JSON-RPC qua **stdout**. Log (pino) trên **stderr** — không redirect stderr nếu cần xem log.

| Tool | Vai trò ngắn |
|------|----------------|
| `remember` | Lưu memory có scope + metadata; dedupe; index Qdrant best-effort |
| `recall` | Truy vấn (vector + metadata), fallback metadata khi lỗi phụ thuộc |
| `get_context_pack` | Gói context (semantic / procedural / episodic) + trường mở rộng cố định |
| `forget_memory` | Soft transition (`archive` / `delete` / `expire`) + audit |
| `update_memory` | Phase 2: cập nhật có **optimistic locking** (`expected_version`); re-index vector; audit `memory.update` |
| `remember_facts` | Phase 2: ghi fact (subject / predicate / object) gắn với `memory_id` đã tồn tại |

`recall` / fallback metadata lọc memory đã **hết hạn** (`expires_at`); có thể bổ sung cảnh báo **CONFLICTING_FACTS** khi hai fact trong workspace mâu thuẫn (cùng subject+predicate, khác object).

Payload chi tiết theo Zod trong `src/contracts/tools/*.ts`.

## Ví dụ cấu hình Cursor

Thêm MCP server trỏ tới entrypoint đã build (hoặc `tsx`):

```json
{
  "mcpServers": {
    "memory-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/Memory-mcp/dist/index.js"],
      "env": {
        "PGHOST": "127.0.0.1",
        "PGPORT": "55432",
        "PGUSER": "memory",
        "PGPASSWORD": "memory",
        "PGDATABASE": "memory_mcp",
        "QDRANT_URL": "http://127.0.0.1:6333",
        "QDRANT_COLLECTION": "memories",
        "EMBEDDING_PROVIDER": "hash",
        "EMBEDDING_DIMENSION": "384"
      }
    }
  }
}
```

Đường dẫn và `env` chỉnh theo máy bạn.

## Chế độ suy giảm (recall / context pack)

Khi embedding hoặc Qdrant lỗi, `recall` vẫn trả **`ok: true`** với retrieval chỉ từ Postgres (metadata / keyword nhẹ), kèm **warnings**:

| Mã | Khi nào |
|----|--------|
| `EMBEDDING_UNAVAILABLE` | `embedder.embed` lỗi |
| `VECTOR_SEARCH_UNAVAILABLE` | `search` Qdrant lỗi (hoặc cảnh báo khi xóa vector lỗi lúc `forget_memory`) |
| `DEGRADED_RETRIEVAL_MODE` | Đang dùng fallback metadata |

Lỗi **business** (input sai, scope, không tìm thấy, v.v.) trả `ok: false` + `error.code` từ `INVALID_INPUT`, `SCOPE_VIOLATION`, `NOT_FOUND`, `DEPENDENCY_UNAVAILABLE`, …

## Tests

```bash
npm test
```

- **Unit**: không cần Docker.
- **Integration** (`src/testing/integration/memoryMcp.int.test.ts`): cần Postgres (và Qdrant cho luồng vector thật trong vài case). Nếu không kết nối được DB trong ~8s, các case đó **bỏ qua** (log cảnh báo), suite vẫn **PASS**.
- Tắt hẳn integration: `SKIP_INTEGRATION=1 npm test`.