From eb1cdabe6167ec985739b09df6edd39bc500cd98 Mon Sep 17 00:00:00 2001 From: kartik-mem0 Date: Thu, 21 May 2026 22:52:27 +0530 Subject: [PATCH] fix(mem0-plugin): remove userConfig from plugin.json, add auto-deps install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove userConfig from .claude-plugin/plugin.json — OAuth flow handles auth via mcp.mem0.ai, userConfig prompt was redundant and confusing - Add ensure_deps.sh to install mem0ai SDK into persistent plugin venv - Add requirements.txt (mem0ai) for dependency tracking - Wire SessionStart hook to auto-install deps on first run - Update setup_coding_categories.py to find venv site-packages - Update onboarding SKILL.md with venv-aware install steps --- mem0-plugin/.claude-plugin/plugin.json | 11 +------ mem0-plugin/hooks/hooks.json | 10 ++++++ mem0-plugin/requirements.txt | 1 + mem0-plugin/scripts/ensure_deps.sh | 32 +++++++++++++++++++ .../scripts/setup_coding_categories.py | 29 +++++++++++------ mem0-plugin/skills/mem0-onboard/SKILL.md | 31 ++++++++++++++---- 6 files changed, 88 insertions(+), 26 deletions(-) create mode 100644 mem0-plugin/requirements.txt create mode 100755 mem0-plugin/scripts/ensure_deps.sh diff --git a/mem0-plugin/.claude-plugin/plugin.json b/mem0-plugin/.claude-plugin/plugin.json index 0dfd89dc2..3e3487fa2 100644 --- a/mem0-plugin/.claude-plugin/plugin.json +++ b/mem0-plugin/.claude-plugin/plugin.json @@ -9,14 +9,5 @@ "homepage": "https://mem0.ai", "repository": "https://github.com/mem0ai/mem0", "license": "Apache-2.0", - "keywords": ["memory", "personalization", "mcp", "semantic-search"], - "userConfig": { - "MEM0_API_KEY": { - "type": "string", - "title": "Mem0 API key", - "description": "Your Mem0 API key (get one at https://app.mem0.ai/dashboard/api-keys or run: mem0 init --agent --json)", - "required": true, - "sensitive": true - } - } + "keywords": ["memory", "personalization", "mcp", "semantic-search"] } diff --git a/mem0-plugin/hooks/hooks.json b/mem0-plugin/hooks/hooks.json index 5f8fad83c..7a2a9664e 100644 --- a/mem0-plugin/hooks/hooks.json +++ b/mem0-plugin/hooks/hooks.json @@ -1,6 +1,16 @@ { "hooks": { "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "diff -q \"${CLAUDE_PLUGIN_ROOT}/requirements.txt\" \"${CLAUDE_PLUGIN_DATA}/requirements.txt\" >/dev/null 2>&1 || \"${CLAUDE_PLUGIN_ROOT}/scripts/ensure_deps.sh\"", + "statusMessage": "Installing mem0 SDK...", + "timeout": 60 + } + ] + }, { "matcher": "startup|resume|compact", "hooks": [ diff --git a/mem0-plugin/requirements.txt b/mem0-plugin/requirements.txt new file mode 100644 index 000000000..633d7eaad --- /dev/null +++ b/mem0-plugin/requirements.txt @@ -0,0 +1 @@ +mem0ai diff --git a/mem0-plugin/scripts/ensure_deps.sh b/mem0-plugin/scripts/ensure_deps.sh new file mode 100755 index 000000000..3b77e1b38 --- /dev/null +++ b/mem0-plugin/scripts/ensure_deps.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Install mem0ai SDK into a persistent venv inside CLAUDE_PLUGIN_DATA. +# Runs on SessionStart; skips if requirements.txt hasn't changed. +set -euo pipefail + +PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}" +DATA_DIR="${CLAUDE_PLUGIN_DATA:-${HOME}/.mem0/plugin-data}" +VENV_DIR="${DATA_DIR}/venv" +REQ_SRC="${PLUGIN_ROOT}/requirements.txt" +REQ_STAMP="${DATA_DIR}/requirements.txt" + +mkdir -p "${DATA_DIR}" + +needs_install=false + +if [ ! -f "${VENV_DIR}/bin/python3" ]; then + needs_install=true +elif ! diff -q "${REQ_SRC}" "${REQ_STAMP}" >/dev/null 2>&1; then + needs_install=true +fi + +if [ "${needs_install}" = "true" ]; then + python3 -m venv "${VENV_DIR}" 2>/dev/null || python -m venv "${VENV_DIR}" + "${VENV_DIR}/bin/pip" install --quiet --upgrade pip >/dev/null 2>&1 || true + if "${VENV_DIR}/bin/pip" install --quiet -r "${REQ_SRC}" 2>/dev/null; then + cp "${REQ_SRC}" "${REQ_STAMP}" + else + rm -f "${REQ_STAMP}" + echo "mem0 plugin: failed to install Python dependencies" >&2 + exit 0 + fi +fi diff --git a/mem0-plugin/scripts/setup_coding_categories.py b/mem0-plugin/scripts/setup_coding_categories.py index b3cd936b4..498ade469 100644 --- a/mem0-plugin/scripts/setup_coding_categories.py +++ b/mem0-plugin/scripts/setup_coding_categories.py @@ -5,15 +5,14 @@ mem0 auto-tags every memory with one or more `categories`. By default the list is consumer-oriented (food, hobbies, music, ...), which is meaningless for code. This script replaces the project's category list with a coding-focused one. -The change is project-level (per the platform docs, per-request overrides are -not supported on the managed API). Run once per project; future memories will -be tagged using the new list automatically. +Uses the mem0ai SDK (client.project.update). The SDK is installed into a +persistent venv at ${CLAUDE_PLUGIN_DATA}/venv by the ensure_deps.sh hook. Usage: - python setup_coding_categories.py # dry-run: show current vs proposed, no changes + python setup_coding_categories.py # dry-run: show current vs proposed python setup_coding_categories.py --apply # actually call project.update() -Requires the mem0ai Python SDK and MEM0_API_KEY (or CLAUDE_PLUGIN_OPTION_MEM0_API_KEY) to be set. +Requires MEM0_API_KEY (or CLAUDE_PLUGIN_OPTION_MEM0_API_KEY). """ from __future__ import annotations @@ -23,8 +22,18 @@ import json import os import sys -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _identity import resolve_api_key +_script_dir = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, _script_dir) +from _identity import resolve_api_key # noqa: E402 + +_plugin_root = os.environ.get("CLAUDE_PLUGIN_ROOT", os.path.join(_script_dir, "..")) +_data_dir = os.environ.get("CLAUDE_PLUGIN_DATA", os.path.join(os.path.expanduser("~"), ".mem0", "plugin-data")) +_venv_site = os.path.join(_data_dir, "venv", "lib") +if os.path.isdir(_venv_site): + for d in sorted(os.listdir(_venv_site)): + sp = os.path.join(_venv_site, d, "site-packages") + if os.path.isdir(sp) and sp not in sys.path: + sys.path.insert(1, sp) CODING_CATEGORIES = [ { @@ -160,9 +169,9 @@ def main() -> int: from mem0 import MemoryClient except ImportError: print( - "ERROR: the mem0ai Python SDK is not installed.\n" - "Install with: pip install mem0ai\n" - "Then re-run this script.", + "ERROR: mem0ai SDK not found. The plugin's ensure_deps.sh hook should\n" + "install it automatically on session start. Try restarting Claude Code,\n" + "or run manually: pip install mem0ai", file=sys.stderr, ) return 1 diff --git a/mem0-plugin/skills/mem0-onboard/SKILL.md b/mem0-plugin/skills/mem0-onboard/SKILL.md index 313b971b2..ecf538f1f 100644 --- a/mem0-plugin/skills/mem0-onboard/SKILL.md +++ b/mem0-plugin/skills/mem0-onboard/SKILL.md @@ -11,12 +11,22 @@ description: > Run this wizard to set up the mem0 plugin for the current project. Complete in ~30 seconds. +## Step 0: Ensure mem0ai SDK is installed + +The plugin installs the `mem0ai` Python SDK automatically on session start via a venv in `${CLAUDE_PLUGIN_DATA}/venv`. If Step 4 (categories) fails with an import error, run: + +```bash +"${CLAUDE_PLUGIN_ROOT}/scripts/ensure_deps.sh" +``` + +This is silent and idempotent — safe to run anytime. + ## Step 1: Verify API key and MCP connection -Check that the mem0 MCP tools are available by looking for `mcp__mem0__search_memories` in the deferred tools list (use ToolSearch if needed). +Check that mem0 MCP tools are available. Use ToolSearch with query `"mem0 search_memories"` — the exact tool name varies by install method (may be `mcp__mem0__search_memories` or `mcp__plugin_mem0_mem0__search_memories`). -- If **MCP tools found**: Proceed to Step 2. The API key is working. -- If **MCP tools NOT found**: The MCP server failed to connect. Tell the user: +- If **any mem0 search tool found**: Proceed to Step 2. The API key is working. +- If **NOT found**: The MCP server failed to connect. Tell the user: 1. "MCP server not connected. Make sure `MEM0_API_KEY` is exported in your shell." 2. Show: `export MEM0_API_KEY="m0-your-key-here"` then restart Claude Code. 3. If they need a key: https://app.mem0.ai/dashboard/api-keys or `mem0 init --agent --json` @@ -53,13 +63,22 @@ If user says yes (or default): Ask: "Install coding categories optimized for development workflows? [Y/n]" -If yes, run the setup script (uses stdlib only, no SDK required): +If yes, run the setup script using the plugin's venv python: ```bash -python3 "${CLAUDE_PLUGIN_ROOT:-${CURSOR_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT}}}/scripts/setup_coding_categories.py" --apply +VENV_PY="${CLAUDE_PLUGIN_DATA}/venv/bin/python3" +if [ -x "${VENV_PY}" ]; then + "${VENV_PY}" "${CLAUDE_PLUGIN_ROOT}/scripts/setup_coding_categories.py" --apply +else + python3 "${CLAUDE_PLUGIN_ROOT}/scripts/setup_coding_categories.py" --apply +fi ``` -If the script reports an error, show the error message and suggest checking the API key. +If the script fails with "mem0ai SDK not found", run the dependency installer first: +```bash +"${CLAUDE_PLUGIN_ROOT}/scripts/ensure_deps.sh" +``` +Then retry the categories script. ## Step 5: Mark project as onboarded