From aa68c8c9d83efacbd67c8501093dab10e2502168 Mon Sep 17 00:00:00 2001 From: XXXVita Date: Wed, 15 Apr 2026 14:34:18 +0300 Subject: [PATCH] fix: register MCP via claude mcp add-json, add memory tool permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude Code reads MCP server config from ~/.claude.json (managed by 'claude mcp' CLI), NOT from ~/.claude/settings.json — writing 'mcpServers' into settings.json is silently ignored. Also adds permissions.allow entries for the 20 memory tools, because without explicit permissions Claude Code prompts for confirmation on every tool call, which breaks automatic recall/save/error logging from hooks. Changes in install.sh: - Step 4: register MCP via 'claude mcp add-json memory ... -s user' instead of editing settings.json; abort with clear message if the 'claude' CLI is missing; remove-then-add makes the step idempotent. - Step 4b2 (new): write permissions.allow with all 20 mcp__memory__* tool names. - Step 6 verify: check registration with 'claude mcp get memory' instead of reading settings.json mcpServers. README updated accordingly. Reapplies the intent of 0659e71 on top of upstream v6.0 (which rewrote README.md and kept the install.sh bug). Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- install.sh | 105 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 76 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index bf59798..d1c47d9 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ The installer: 2. Sets up Python venv in `~/claude-memory-server/.venv/` 3. Installs deps from `requirements.txt` and `requirements-dev.txt` 4. Pre-downloads the FastEmbed multilingual MiniLM model -5. Wires the MCP server into `~/.claude/settings.json` +5. Registers the MCP server via `claude mcp add-json` (stored in `~/.claude.json`) and grants `permissions.allow` for memory tools in `~/.claude/settings.json` 6. Applies all migrations 001..007 to a fresh `memory.db` 7. Optionally installs LaunchAgents (reflection + orphan backfill + check-updates) 8. Starts the dashboard at `http://127.0.0.1:37737` diff --git a/install.sh b/install.sh index 1db7f3b..c9384e6 100755 --- a/install.sh +++ b/install.sh @@ -65,36 +65,31 @@ mkdir -p "$HOME/.claude" PY_PATH="$VENV_DIR/bin/python" SRV_PATH="$INSTALL_DIR/src/server.py" -python3 -c " -import json, os +# Claude Code reads MCP server config from ~/.claude.json (managed via the +# 'claude mcp' CLI), NOT from ~/.claude/settings.json — writing 'mcpServers' +# into settings.json is silently ignored by Claude Code. +if ! command -v claude &>/dev/null; then + echo " ERROR: 'claude' CLI not found in PATH." + echo " Install Claude Code first: https://claude.com/claude-code" + exit 1 +fi -settings_path = '$CLAUDE_SETTINGS' -new_server = { +MCP_JSON=$(python3 -c " +import json +print(json.dumps({ 'command': '$PY_PATH', 'args': ['$SRV_PATH'], 'env': { 'CLAUDE_MEMORY_DIR': '$MEMORY_DIR', 'EMBEDDING_MODEL': 'all-MiniLM-L6-v2' } -} - -settings = {} -if os.path.exists(settings_path): - try: - with open(settings_path) as f: - settings = json.load(f) - except: - pass +})) +") -if 'mcpServers' not in settings: - settings['mcpServers'] = {} -settings['mcpServers']['memory'] = new_server - -with open(settings_path, 'w') as f: - json.dump(settings, f, indent=2) - -print(' OK: MCP server added to ' + settings_path) -" +# Remove any previous registration (ignore errors if absent), then add fresh +claude mcp remove memory -s user >/dev/null 2>&1 || true +claude mcp add-json memory "$MCP_JSON" -s user +echo " OK: MCP server 'memory' registered via 'claude mcp add-json' (user scope)" # -- 4b. Register hooks in settings.json -- echo "-> Step 4b: Registering hooks..." @@ -146,6 +141,58 @@ with open(settings_path, 'w') as f: print(' OK: Hooks registered (SessionStart, SessionEnd, Stop, PostToolUse:Bash/Write|Edit)') " +# -- 4b2. Grant permissions for MCP memory tools -- +# Without these, Claude Code prompts for confirmation on every memory tool call, +# which breaks automatic recall/save/error logging from hooks. +echo "-> Step 4b2: Granting permissions for memory tools..." + +python3 -c " +import json, os + +settings_path = '$CLAUDE_SETTINGS' +settings = {} +if os.path.exists(settings_path): + with open(settings_path) as f: + settings = json.load(f) + +settings.setdefault('permissions', {}).setdefault('allow', []) +allow = settings['permissions']['allow'] + +memory_tools = [ + 'mcp__memory__memory_recall', + 'mcp__memory__memory_save', + 'mcp__memory__memory_update', + 'mcp__memory__memory_timeline', + 'mcp__memory__memory_stats', + 'mcp__memory__memory_consolidate', + 'mcp__memory__memory_export', + 'mcp__memory__memory_forget', + 'mcp__memory__memory_history', + 'mcp__memory__memory_delete', + 'mcp__memory__memory_relate', + 'mcp__memory__memory_search_by_tag', + 'mcp__memory__memory_extract_session', + 'mcp__memory__memory_observe', + 'mcp__memory__self_error_log', + 'mcp__memory__self_insight', + 'mcp__memory__self_rules', + 'mcp__memory__self_patterns', + 'mcp__memory__self_reflect', + 'mcp__memory__self_rules_context', +] + +added = 0 +for tool in memory_tools: + if tool not in allow: + allow.append(tool) + added += 1 + +with open(settings_path, 'w') as f: + json.dump(settings, f, indent=2) + +print(f' OK: {len(memory_tools)} memory tools in permissions.allow (+{added} new)') +" + # -- 4c. Ollama check + optional install prompt -- echo "" echo "-> Step 4c: Checking Ollama (optional but strongly recommended)..." @@ -201,14 +248,12 @@ else echo " FAIL: Server not found at $SRV_PATH" fi -# Check settings.json -python3 -c " -import json -with open('$CLAUDE_SETTINGS') as f: - s = json.load(f) -assert 'memory' in s.get('mcpServers', {}) -print(' OK: MCP server configured') -" 2>/dev/null || echo " FAIL: MCP config issue" +# Check MCP registration (lives in ~/.claude.json, not settings.json) +if claude mcp get memory >/dev/null 2>&1; then + echo " OK: MCP server 'memory' registered" +else + echo " FAIL: MCP config issue — run 'claude mcp list' to debug" +fi # Check memory dir if [ -d "$MEMORY_DIR" ]; then