Installation¶
Prerequisites¶
- Codex CLI v0.116.0+
- Python 3.10+
- memsearch installed:
uv tool install "memsearch[onnx]"
Install¶
# 1. Clone the memsearch repo (if not already)
git clone https://github.com/zilliztech/memsearch.git
# 2. Run the installer
bash memsearch/plugins/codex/scripts/install.sh
The installer:
- Copies the memory-recall skill to
~/.agents/skills/ - Installs or updates memsearch hooks in
~/.codex/hooks.json - Enables
hooks = truein~/.codex/config.toml - Makes all scripts executable
Usage¶
Why full access?
Codex needs full access on the first run because the ONNX embedding model downloads from HuggingFace Hub (network access required). After the model is cached, full access is still the safest default because hooks execute shell commands. On current Codex builds, --dangerously-bypass-approvals-and-sandbox is the explicit full-access flag. Some builds may also accept the older --yolo alias.
Pre-cache the Model (optional)¶
Configuration¶
Embedding Provider¶
Default: onnx (bge-m3, CPU, no API key). Change with:
Milvus Backend¶
Default: Milvus Lite (~/.memsearch/milvus.db). For remote Milvus:
Uninstall¶
python3 - <<'PY'
from pathlib import Path
import json
import shutil
skill_dir = Path.home() / ".agents/skills/memory-recall"
if skill_dir.is_symlink() or skill_dir.is_file():
skill_dir.unlink()
elif skill_dir.exists():
shutil.rmtree(skill_dir)
hooks_file = Path.home() / ".codex/hooks.json"
markers = {
"SessionStart": "plugins/codex/hooks/session-start.sh",
"UserPromptSubmit": "plugins/codex/hooks/user-prompt-submit.sh",
"Stop": "plugins/codex/hooks/stop.sh",
}
if hooks_file.exists():
data = json.loads(hooks_file.read_text())
hooks = data.get("hooks", {}) if isinstance(data, dict) else {}
for event, marker in markers.items():
kept_entries = []
for entry in hooks.get(event, []):
if not isinstance(entry, dict):
continue
kept_hooks = []
for hook in entry.get("hooks", []):
command = hook.get("command", "") if isinstance(hook, dict) else ""
if marker not in command:
kept_hooks.append(hook)
if kept_hooks:
updated = dict(entry)
updated["hooks"] = kept_hooks
kept_entries.append(updated)
if kept_entries:
hooks[event] = kept_entries
else:
hooks.pop(event, None)
if hooks:
data["hooks"] = hooks
hooks_file.write_text(json.dumps(data, indent=2) + "\\n")
else:
hooks_file.unlink()
PY
# Optionally disable hooks in ~/.codex/config.toml if you have no other hooks.
# Optionally remove memsearch itself:
uv tool uninstall memsearch
This removes only memsearch's Codex hook entries and skill. It preserves unrelated Codex hooks and does not delete project memory files in .memsearch/memory/.