Openmemory Codex Local Setup

1. OpenMemory 本机部署并接入 Codex

1.1. 目标

本机运行 OpenMemory MCP:

  • LLM:使用在线 OpenAI 兼容平台,配置 base_urlapi_key
  • Embedding:使用 Docker 本机部署轻量模型 BAAI/bge-small-zh-v1.5
  • Codex:通过本机 MCP URL 连接 OpenMemory

1.2. 启动本机 Embedding 服务

启动 TEI 容器:

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

验证:

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

把:

RUN pip install -r requirements.txt

改成:

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

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

把:

memories = memory_client.get_all(user_id=uid)

改成:

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

1.5.2. 修复 search_memory

同一文件中,把:

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

改成:

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() 开头加入:

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 创建后加入:

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 的签名改成:

def _build_openai_embedder_config(model, api_key, base_url, ollama_base_url, llm_base_url, embedding_dims=None):
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:

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

验证 API:

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

期望输出:

200

验证 MCP 初始化:

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 工具列表:

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

编辑:

~/.codex/config.toml

追加:

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

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

1.8. 常用命令

查看 OpenMemory 容器:

cd openmemory
docker compose ps

重启 OpenMemory MCP:

cd openmemory
docker compose restart openmemory-mcp

重建 OpenMemory MCP:

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

删除错误维度的 Qdrant collection:

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,删除后重建:

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

1.9.3. 为什么 list_memoriesuser_id 参数错误?

新版 mem0ai 不再支持 get_all(user_id=...),要改成:

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

1.9.4. 为什么 search_memoryunexpected keyword argument 'limit'

新版 Qdrant vector store 使用 top_k,不是 limit

1.9.5. 为什么不启动 OpenMemory UI?

OpenMemory UI 默认占用 3000,容易和 Mem0 dashboard 冲突。Codex MCP 只需要 openmemory-mcpmem0_store

1.9.6. http://localhost:3000/dashboard/memories 还需要吗?

不需要。

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

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 客户端,不负责存储记忆。必须保留:

cd openmemory
docker compose up -d mem0_store openmemory-mcp

如果 embedding 使用本机 TEI,也必须保留:

docker start mem0-embedding

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

1.9.8. OpenMemory MCP 的数据存在哪里?

主要存储在 Qdrant 的 Docker volume:

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

查看 volume:

docker volume inspect openmemory_mem0_storage

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

1.9.9. 如何查看 OpenMemory 的 Qdrant 数据?

查看 collections:

curl http://127.0.0.1:6333/collections

查看 openmemory collection:

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

1.9.10. 如何清空 OpenMemory 记忆?

删除 Qdrant collection:

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

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

1.9.11. infer=true 什么时候能用?

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

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

不想调用 LLM 时,写入记忆用 infer=false

评论