Initial commit: claude-automation 🦊
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 💕
This commit is contained in:
317
setup_matrix.sh
Executable file
317
setup_matrix.sh
Executable file
@@ -0,0 +1,317 @@
|
||||
#!/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 ""
|
||||
Reference in New Issue
Block a user