# 1. OpenMemory 本机部署并接入 Codex

## 1.1. 目标

本机运行 OpenMemory MCP：

- LLM：使用在线 OpenAI 兼容平台，配置 `base_url` 和 `api_key`
- Embedding：使用 Docker 本机部署轻量模型 `BAAI/bge-small-zh-v1.5`
- Codex：通过本机 MCP URL 连接 OpenMemory

## 1.2. 启动本机 Embedding 服务

启动 TEI 容器：

```bash
docker run -d \
  --name mem0-embedding \
  -p 8080:80 \
  ghcr.io/huggingface/text-embeddings-inference:cpu-latest \
  --model-id BAAI/bge-small-zh-v1.5
```

验证：

```bash
curl -s http://127.0.0.1:8080/v1/embeddings \
  -H 'Content-Type: application/json' \
  -d '{"input":"测试 embedding","model":"BAAI/bge-small-zh-v1.5"}'
```

该模型输出维度是 `512`。

## 1.3. 修改 OpenMemory Dockerfile 加速构建

文件：`openmemory/api/Dockerfile`

把：

```dockerfile
RUN pip install -r requirements.txt
```

改成：

```dockerfile
ARG PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
ARG PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn
RUN pip install --no-cache-dir -i ${PIP_INDEX_URL} --trusted-host ${PIP_TRUSTED_HOST} -r requirements.txt
```

## 1.4. 配置 OpenMemory 环境变量

文件：`openmemory/api/.env`

```env
USER=team-default

OPENAI_API_KEY=<your-compatible-api-key>
LLM_PROVIDER=openai
LLM_MODEL=<your-chat-model>
LLM_API_KEY=<your-compatible-api-key>
LLM_BASE_URL=<your-compatible-openai-base-url>

EMBEDDER_PROVIDER=openai
EMBEDDER_MODEL=BAAI/bge-small-zh-v1.5
EMBEDDER_API_KEY=local-embedding
EMBEDDER_BASE_URL=http://host.docker.internal:8080/v1
EMBEDDER_DIMS=512
```

说明：

- `LLM_*` 填在线 OpenAI 兼容平台。
- `EMBEDDER_*` 指向本机 Docker embedding 服务。
- 容器内访问宿主机服务要用 `host.docker.internal`。

## 1.5. 修复 OpenMemory 与 mem0ai 2.x 的兼容问题

### 1.5.1. 修复 `list_memories`

文件：`openmemory/api/app/mcp_server.py`

把：

```python
memories = memory_client.get_all(user_id=uid)
```

改成：

```python
memories = memory_client.get_all(filters={"user_id": uid})
```

### 1.5.2. 修复 `search_memory`

同一文件中，把：

```python
hits = memory_client.vector_store.search(
    query=query,
    vectors=embeddings,
    limit=10,
    filters=filters,
)
```

改成：

```python
hits = memory_client.vector_store.search(
    query=query,
    vectors=embeddings,
    top_k=10,
    filters=filters,
)
```

### 1.5.3. 让 Qdrant 使用 512 维

文件：`openmemory/api/app/utils/memory.py`

在 `get_default_memory_config()` 开头加入：

```python
embedder_dims = os.environ.get('EMBEDDER_DIMS') or os.environ.get('EMBEDDER_DIMENSIONS')
embedder_dims = int(embedder_dims) if embedder_dims else None
```

在 `vector_store_config` 创建后加入：

```python
if embedder_dims:
    vector_store_config["embedding_model_dims"] = embedder_dims
```

把 `_create_embedder_config` 改成接受 `embedding_dims=None`，并向 provider factory 传递该参数。

把 `_build_openai_embedder_config` 和 `_build_ollama_embedder_config` 的签名改成：

```python
def _build_openai_embedder_config(model, api_key, base_url, ollama_base_url, llm_base_url, embedding_dims=None):
```

```python
def _build_ollama_embedder_config(model, api_key, base_url, ollama_base_url, llm_base_url, embedding_dims=None):
```

不要把 `embedding_dims` 写入 OpenAI embedder config；这里只用于 Qdrant collection 维度。

## 1.6. 启动 OpenMemory MCP

只启动 MCP API 和 Qdrant，不启动 UI：

```bash
cd openmemory
docker compose up -d --build mem0_store openmemory-mcp
```

验证 API：

```bash
curl -s -o /tmp/openmemory_docs_status.txt -w '%{http_code}' http://127.0.0.1:8765/docs
```

期望输出：

```text
200
```

验证 MCP 初始化：

```bash
curl -s -X POST http://127.0.0.1:8765/mcp/codex/http/team-default \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"codex","version":"test"}}}'
```

验证 MCP 工具列表：

```bash
curl -s -X POST http://127.0.0.1:8765/mcp/codex/http/team-default \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
```

应该能看到：

- `add_memories`
- `search_memory`
- `list_memories`
- `delete_memories`
- `delete_all_memories`

## 1.7. 配置 Codex MCP

编辑：

```text
~/.codex/config.toml
```

追加：

```toml
[mcp_servers.openmemory_team]
url = "http://127.0.0.1:8765/mcp/codex/http/team-default"
```

重启 Codex 或新开 Codex 会话，让 MCP 配置重新加载。

## 1.8. 常用命令

查看 OpenMemory 容器：

```bash
cd openmemory
docker compose ps
```

重启 OpenMemory MCP：

```bash
cd openmemory
docker compose restart openmemory-mcp
```

重建 OpenMemory MCP：

```bash
cd openmemory
docker compose up -d --build openmemory-mcp
```

删除错误维度的 Qdrant collection：

```bash
curl -s -X DELETE http://127.0.0.1:6333/collections/openmemory
```

## 1.9. FAQ

### 1.9.1. Docker 镜像源换成国内源后为什么还是慢？

Docker 镜像源只影响拉镜像。OpenMemory 慢主要是 Dockerfile 里 `pip install` 下载 Python 包，所以要改 PyPI 源。

### 1.9.2. 为什么 embedding 写入时报 `expected dim: 1536, got 512`？

OpenMemory 默认按 OpenAI embedding 的 1536 维创建 Qdrant collection。本地模型 `BAAI/bge-small-zh-v1.5` 是 512 维，需要设置 `EMBEDDER_DIMS=512`，并让 Qdrant 配置使用 `embedding_model_dims=512`。

如果已经创建了错误 collection，删除后重建：

```bash
curl -s -X DELETE http://127.0.0.1:6333/collections/openmemory
```

### 1.9.3. 为什么 `list_memories` 报 `user_id` 参数错误？

新版 `mem0ai` 不再支持 `get_all(user_id=...)`，要改成：

```python
get_all(filters={"user_id": uid})
```

### 1.9.4. 为什么 `search_memory` 报 `unexpected keyword argument 'limit'`？

新版 Qdrant vector store 使用 `top_k`，不是 `limit`。

### 1.9.5. 为什么不启动 OpenMemory UI？

OpenMemory UI 默认占用 `3000`，容易和 Mem0 dashboard 冲突。Codex MCP 只需要 `openmemory-mcp` 和 `mem0_store`。

### 1.9.6. `http://localhost:3000/dashboard/memories` 还需要吗？

不需要。

这个页面属于 Mem0 server/dashboard，不属于 OpenMemory MCP。Codex 当前连接的是：

```text
http://127.0.0.1:8765/mcp/codex/http/team-default
```

除非还要单独使用 Mem0 server dashboard，否则可以停掉 `localhost:3000` 那套服务。

### 1.9.7. Codex MCP 还需要 server 吗？

需要 OpenMemory MCP server。

Codex 是 MCP 客户端，不负责存储记忆。必须保留：

```bash
cd openmemory
docker compose up -d mem0_store openmemory-mcp
```

如果 embedding 使用本机 TEI，也必须保留：

```bash
docker start mem0-embedding
```

不需要再跑 Mem0 仓库里的 `server/` REST API。

### 1.9.8. OpenMemory MCP 的数据存在哪里？

主要存储在 Qdrant 的 Docker volume：

```text
Docker volume: openmemory_mem0_storage
容器内路径: /mem0/storage
```

查看 volume：

```bash
docker volume inspect openmemory_mem0_storage
```

macOS Docker Desktop 下，volume 实际文件在 Docker Desktop 的 Linux VM 里，不建议直接手动编辑。

### 1.9.9. 如何查看 OpenMemory 的 Qdrant 数据？

查看 collections：

```bash
curl http://127.0.0.1:6333/collections
```

查看 `openmemory` collection：

```bash
curl http://127.0.0.1:6333/collections/openmemory
```

### 1.9.10. 如何清空 OpenMemory 记忆？

删除 Qdrant collection：

```bash
curl -X DELETE http://127.0.0.1:6333/collections/openmemory
```

这会清掉向量记忆。只有确定要清空时再执行。

### 1.9.11. `infer=true` 什么时候能用？

只有在线 LLM 配好后才能稳定使用：

```env
LLM_MODEL=<your-chat-model>
LLM_API_KEY=<your-compatible-api-key>
LLM_BASE_URL=<your-compatible-openai-base-url>
```

不想调用 LLM 时，写入记忆用 `infer=false`。
