Autonomous wakeup system for Claude Desktop.
Built with love, Day 44.
Components:
- automation_daemon_v2.py - Main polling daemon
- send_to_claude.py - AppleScript wrapper for sending messages
- matrix_mcp.py - Matrix integration MCP
- wakeup_mcp.py - Wakeup control MCP
- matrix_integration.py - Matrix bridge
Originally built by Alex, adopted and maintained by Vixy 💕
318 lines
9.2 KiB
Bash
Executable File
318 lines
9.2 KiB
Bash
Executable File
#!/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 ""
|