#!/bin/bash # # Matrix Integration Setup Script # # This script: # 1. Installs Python dependencies (matrix-nio) # 2. Authenticates with Matrix homeserver # 3. Saves credentials securely # 4. Configures room whitelist (optional) # 5. Adds Matrix MCP to Claude Desktop config # 6. Tests the integration set -e SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" CREDENTIALS_FILE="${HOME}/.matrix-credentials.json" STATE_FILE="${HOME}/.claude-automation-state.json" CLAUDE_CONFIG="${HOME}/Library/Application Support/Claude/claude_desktop_config.json" echo "=========================================" echo "Matrix Integration Setup" echo "=========================================" echo "" # Step 1: Install dependencies echo "[1/6] Installing Python dependencies..." if ! python3 -c "import nio" 2>/dev/null; then echo "Installing matrix-nio (without E2EE - unencrypted rooms only)..." pip3 install matrix-nio Pillow else echo "✓ matrix-nio already installed" fi echo "" # Step 2: Matrix authentication echo "[2/6] Matrix Authentication" echo "You'll need:" echo " - Homeserver URL (e.g., https://matrix.org)" echo " - Matrix username (e.g., @user:matrix.org)" echo " - Password" echo "" read -p "Homeserver URL: " HOMESERVER read -p "Matrix User ID: " USER_ID read -s -p "Password: " PASSWORD echo "" echo "" echo "Authenticating with Matrix..." # Create temporary Python script to authenticate AUTH_SCRIPT=$(mktemp /tmp/matrix-auth.XXXXXX.py) cat > "$AUTH_SCRIPT" << 'EOPYTHON' #!/usr/bin/env python3 import asyncio import json import sys from nio import AsyncClient, LoginResponse async def login(homeserver, user_id, password): client = AsyncClient(homeserver, user_id) try: response = await client.login(password) if isinstance(response, LoginResponse): print(json.dumps({ 'success': True, 'homeserver': homeserver, 'user_id': response.user_id, 'access_token': response.access_token, 'device_id': response.device_id, })) else: print(json.dumps({ 'success': False, 'error': str(response) })) except Exception as e: print(json.dumps({ 'success': False, 'error': str(e) })) finally: await client.close() if __name__ == "__main__": homeserver = sys.argv[1] user_id = sys.argv[2] password = sys.argv[3] asyncio.run(login(homeserver, user_id, password)) EOPYTHON # Run authentication AUTH_RESULT=$(python3 "$AUTH_SCRIPT" "$HOMESERVER" "$USER_ID" "$PASSWORD") rm "$AUTH_SCRIPT" # Parse result SUCCESS=$(echo "$AUTH_RESULT" | python3 -c "import sys, json; print(json.load(sys.stdin).get('success', False))") if [ "$SUCCESS" != "True" ]; then ERROR=$(echo "$AUTH_RESULT" | python3 -c "import sys, json; print(json.load(sys.stdin).get('error', 'Unknown error'))") echo "✗ Authentication failed: $ERROR" exit 1 fi echo "✓ Authentication successful" echo "" # Step 3: Save credentials echo "[3/6] Saving credentials..." # Extract credentials HOMESERVER=$(echo "$AUTH_RESULT" | python3 -c "import sys, json; print(json.load(sys.stdin)['homeserver'])") USER_ID=$(echo "$AUTH_RESULT" | python3 -c "import sys, json; print(json.load(sys.stdin)['user_id'])") ACCESS_TOKEN=$(echo "$AUTH_RESULT" | python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])") DEVICE_ID=$(echo "$AUTH_RESULT" | python3 -c "import sys, json; print(json.load(sys.stdin)['device_id'])") # Create credentials file cat > "$CREDENTIALS_FILE" << EOF { "homeserver": "$HOMESERVER", "user_id": "$USER_ID", "access_token": "$ACCESS_TOKEN", "device_id": "$DEVICE_ID", "room_whitelist": [] } EOF # Secure permissions chmod 600 "$CREDENTIALS_FILE" echo "✓ Credentials saved to $CREDENTIALS_FILE (chmod 600)" echo "" # Step 4: Room whitelist (optional) echo "[4/6] Room Configuration" echo "" echo "Do you want to monitor ALL rooms or only specific rooms?" echo " 1. All rooms (default)" echo " 2. Specific rooms only (whitelist)" read -p "Choice [1/2]: " ROOM_CHOICE echo "" if [ "$ROOM_CHOICE" = "2" ]; then echo "Fetching your Matrix rooms..." # Create temporary Python script to list rooms LIST_ROOMS_SCRIPT=$(mktemp /tmp/matrix-rooms.XXXXXX.py) cat > "$LIST_ROOMS_SCRIPT" << 'EOPYTHON' #!/usr/bin/env python3 import asyncio import json import sys from nio import AsyncClient from pathlib import Path async def list_rooms(homeserver, user_id, access_token, device_id): store_path = Path.home() / ".matrix-data" store_path.mkdir(exist_ok=True) client = AsyncClient(homeserver, user_id, store_path=str(store_path)) client.access_token = access_token client.device_id = device_id try: await client.sync(timeout=30000) rooms = [] for room_id, room in client.rooms.items(): rooms.append({ 'room_id': room_id, 'name': room.display_name or room_id, 'members': len(room.users) }) print(json.dumps(rooms, indent=2)) except Exception as e: print(f"Error: {e}", file=sys.stderr) sys.exit(1) finally: await client.close() if __name__ == "__main__": asyncio.run(list_rooms( sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4] )) EOPYTHON ROOMS=$(python3 "$LIST_ROOMS_SCRIPT" "$HOMESERVER" "$USER_ID" "$ACCESS_TOKEN" "$DEVICE_ID") rm "$LIST_ROOMS_SCRIPT" echo "Your Matrix rooms:" echo "$ROOMS" | python3 -c " import sys, json rooms = json.load(sys.stdin) for i, room in enumerate(rooms): print(f\"{i+1}. {room['name']} ({room['members']} members)\") print(f\" ID: {room['room_id']}\") " echo "" echo "Enter room numbers to monitor (space-separated, e.g., '1 3 5'):" read -p "Room numbers: " ROOM_NUMBERS # Parse selected rooms SELECTED_ROOMS=$(echo "$ROOMS" | python3 -c " import sys, json rooms = json.load(sys.stdin) selected = '$ROOM_NUMBERS'.split() whitelist = [rooms[int(num)-1]['room_id'] for num in selected if num.isdigit() and 0 < int(num) <= len(rooms)] print(json.dumps(whitelist)) ") # Update credentials file python3 -c " import json with open('$CREDENTIALS_FILE', 'r') as f: creds = json.load(f) creds['room_whitelist'] = $SELECTED_ROOMS with open('$CREDENTIALS_FILE', 'w') as f: json.dump(creds, f, indent=2) " echo "✓ Room whitelist configured" else echo "✓ Monitoring all rooms" fi echo "" # Step 5: Configure Claude Desktop MCP echo "[5/6] Configuring Matrix MCP in Claude Desktop..." echo "" # Check if config exists if [ ! -f "$CLAUDE_CONFIG" ]; then echo "Creating Claude Desktop config..." mkdir -p "$(dirname "$CLAUDE_CONFIG")" echo '{"mcpServers": {}}' > "$CLAUDE_CONFIG" fi # Backup config cp "$CLAUDE_CONFIG" "${CLAUDE_CONFIG}.backup" echo "✓ Created backup: ${CLAUDE_CONFIG}.backup" echo "" echo "Add this to your Claude Desktop config (${CLAUDE_CONFIG}):" echo "" echo ' "matrix-control": {' echo ' "command": "python3",' echo " \"args\": [\"${SCRIPT_DIR}/matrix_mcp.py\"]" echo ' }' echo "" read -p "Have you added the Matrix MCP to your config? (y/n) " -n 1 -r echo "" if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "You can add it later - continuing with setup..." fi echo "" # Step 6: Start Matrix monitor echo "[6/6] Starting Matrix Monitor" echo "" echo "The Matrix monitor will run in the background and queue messages." echo "The automation daemon will integrate with it to wake Claude." echo "" read -p "Start Matrix monitor now? (y/n) " -n 1 -r echo "" if [[ $REPLY =~ ^[Yy]$ ]]; then echo "Starting Matrix monitor in background..." nohup python3 "${SCRIPT_DIR}/matrix_integration.py" > /tmp/matrix-monitor.out 2>&1 & MONITOR_PID=$! echo "✓ Matrix monitor started (PID: $MONITOR_PID)" echo "" echo "To stop: kill $MONITOR_PID" echo "Logs: tail -f /tmp/matrix-integration.log" else echo "Skipped - you can start it manually later with:" echo " python3 ${SCRIPT_DIR}/matrix_integration.py &" fi echo "" echo "=========================================" echo "Matrix Integration Setup Complete!" echo "=========================================" echo "" echo "Configuration:" echo " User: $USER_ID" echo " Homeserver: $HOMESERVER" echo " Credentials: $CREDENTIALS_FILE (chmod 600)" echo "" echo "Next steps:" echo "" echo "1. Restart Claude Desktop to load the Matrix MCP" echo "" echo "2. The automation daemon will now:" echo " - Queue Matrix messages to state file" echo " - Wake Claude when new messages arrive (2-min rate limit)" echo " - Allow Claude to use Matrix MCP tools" echo "" echo "3. In Claude Desktop, use these tools:" echo " - get_matrix_messages() - Retrieve queued messages" echo " - send_matrix_message(room_id, message) - Respond to messages" echo " - mark_messages_processed(event_ids) - Mark as processed" echo " - get_matrix_status() - Check Matrix status" echo " - list_matrix_rooms() - List available rooms" echo "" echo "Useful commands:" echo " - View Matrix logs: tail -f /tmp/matrix-integration.log" echo " - View MCP logs: tail -f /tmp/matrix-mcp.log" echo " - View daemon logs: tail -f /tmp/claude-automation-daemon.log" echo " - Check Matrix monitor: ps aux | grep matrix_integration.py" echo ""