Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
105 changes: 75 additions & 30 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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..."
Expand Down Expand Up @@ -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)..."
Expand Down Expand Up @@ -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
Expand Down