mirror of
https://github.com/aaronjmars/opendia.git
synced 2025-12-29 16:16:00 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99d31b15c8 | ||
|
|
a83df06513 | ||
|
|
05559b8b1d | ||
|
|
ca1a88776d | ||
|
|
14be38dd16 | ||
|
|
aa78576ad7 | ||
|
|
f57010971a | ||
|
|
e40805801a | ||
|
|
c3c77c1e04 | ||
|
|
23eda72d91 | ||
|
|
b131e05513 | ||
|
|
019df3b3b0 | ||
|
|
42e465045c |
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 OpenDia Team
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
118
README.md
118
README.md
@@ -1,9 +1,10 @@
|
|||||||
# OpenDia <img src="opendia-extension/icon-128.png" alt="OpenDia" width="32" height="32">
|
# OpenDia <img src="opendia-extension/icon-128.png" alt="OpenDia" width="32" height="32">
|
||||||
|
|
||||||
> **The open alternative to Dia**
|
**The open alternative to Dia**
|
||||||
> Connect your browser to AI models. No browser switching needed—works seamlessly with any Chromium browser including Chrome & Arc.
|
Connect your browser to AI models. No browser switching needed—works seamlessly with any Chromium browser including Chrome & Arc.
|
||||||
|
|
||||||
[](https://badge.fury.io/js/opendia)
|
[](https://www.npmjs.com/package/opendia)
|
||||||
|
[](https://github.com/aaronjmars/opendia/releases/latest)
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
## 📺 See it in Action
|
## 📺 See it in Action
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
OpenDia lets AI models control your browser automatically. **The key advantage? It leverages everything you already have**—your logged-in accounts, saved passwords, cookies, wallets, and browsing history. No need to start from scratch or switch contexts.
|
OpenDia lets AI models control your browser automatically. **The key advantage? It leverages everything you already have**—your logged-in accounts, saved passwords, cookies, wallets, and browsing history. No need to start from scratch or switch contexts.
|
||||||
|
|
||||||
**🔑 Use Your Existing Digital Life:**
|
**🔑 Use Your Existing Digital Life:**
|
||||||
- ✅ **Logged-in accounts**: Post to Twitter / X, LinkedIn, Facebook with your existing sessions
|
- ✅ **Logged-in accounts**: Post to Twitter/X, LinkedIn, Facebook with your existing sessions
|
||||||
- ✅ **Browser data**: Access your bookmarks, history, and saved passwords
|
- ✅ **Browser data**: Access your bookmarks, history, and saved passwords
|
||||||
- ✅ **Extensions & wallets**: Use MetaMask, password managers, or any installed extensions
|
- ✅ **Extensions & wallets**: Use MetaMask, password managers, or any installed extensions
|
||||||
- ✅ **Cookies & sessions**: Stay authenticated across all your favorite sites
|
- ✅ **Cookies & sessions**: Stay authenticated across all your favorite sites
|
||||||
@@ -32,12 +33,11 @@ OpenDia lets AI models control your browser automatically. **The key advantage?
|
|||||||
|
|
||||||
Works with **any Chromium-based browser**:
|
Works with **any Chromium-based browser**:
|
||||||
- ✅ **Google Chrome**
|
- ✅ **Google Chrome**
|
||||||
- ✅ **Arc Browser**
|
- ✅ **Arc**
|
||||||
- ✅ **Microsoft Edge**
|
- ✅ **Microsoft Edge**
|
||||||
- ✅ **Brave Browser**
|
- ✅ **Brave**
|
||||||
- ✅ **Opera**
|
- ✅ **Opera**
|
||||||
- ✅ **Vivaldi**
|
- ✅ **Any Chromium based browser**
|
||||||
- ✅ **Any Chromium variant**
|
|
||||||
|
|
||||||
Perfect for **Cursor users** who want to automate their local testing and development workflows!
|
Perfect for **Cursor users** who want to automate their local testing and development workflows!
|
||||||
|
|
||||||
@@ -69,21 +69,30 @@ Perfect for **Cursor users** who want to automate their local testing and develo
|
|||||||
- **"Monitor this webpage and notify me when the content changes"**
|
- **"Monitor this webpage and notify me when the content changes"**
|
||||||
- **"Automatically bookmark interesting articles I'm reading"**
|
- **"Automatically bookmark interesting articles I'm reading"**
|
||||||
|
|
||||||
|
### 🎨 Visual Customization & Fun
|
||||||
|
- **"Apply a cyberpunk theme to this documentation site to make it more engaging"**
|
||||||
|
- **"Make this page dark mode with green text for late-night reading"**
|
||||||
|
- **"Add rainbow party effects to celebrate finishing this project"**
|
||||||
|
- **"Transform this boring form with a retro 80s theme while I fill it out"**
|
||||||
|
- **"Use high contrast styling so I can read this better"**
|
||||||
|
|
||||||
## ⚡ Quick Start
|
## ⚡ Quick Start
|
||||||
|
|
||||||
### 1. Start the Server
|
### 1. Install the Browser Extension
|
||||||
```bash
|
|
||||||
npx opendia
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Install the Browser Extension
|
|
||||||
1. Download from [releases](https://github.com/aaronjmars/opendia/releases)
|
1. Download from [releases](https://github.com/aaronjmars/opendia/releases)
|
||||||
2. Go to `chrome://extensions/` (or your browser's extension page)
|
2. Go to `chrome://extensions/` (or your browser's extension page)
|
||||||
3. Enable "Developer mode"
|
3. Enable "Developer mode"
|
||||||
4. Click "Load unpacked" and select the extension folder
|
4. Click "Load unpacked" and select the extension folder
|
||||||
|
|
||||||
### 3. Connect to Your AI
|
### 2. Connect to Your AI
|
||||||
**For Claude Desktop**, add to your configuration:
|
|
||||||
|
**Option 1: Double-click Installation (Recommended)**
|
||||||
|
1. Download the `opendia.dxt` file from [releases](https://github.com/aaronjmars/opendia/releases)
|
||||||
|
2. Double-click the `.dxt` file to install automatically
|
||||||
|
3. The MCP will be added to your Claude Desktop configuration
|
||||||
|
|
||||||
|
**Option 2: Manual Configuration**
|
||||||
|
Add to your Claude Desktop configuration:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
@@ -97,9 +106,67 @@ npx opendia
|
|||||||
|
|
||||||
**For Cursor or other AI tools**, use the same configuration or follow their specific setup instructions.
|
**For Cursor or other AI tools**, use the same configuration or follow their specific setup instructions.
|
||||||
|
|
||||||
|
## Usage Modes
|
||||||
|
|
||||||
|
### Local Mode (Default)
|
||||||
|
```bash
|
||||||
|
npx opendia
|
||||||
|
```
|
||||||
|
- Chrome extension: ws://localhost:5555 (auto-discovery enabled)
|
||||||
|
- Claude Desktop: stdio (existing config)
|
||||||
|
- Local SSE: http://localhost:5556/sse
|
||||||
|
|
||||||
|
### Port Configuration
|
||||||
|
```bash
|
||||||
|
# Use custom ports
|
||||||
|
npx opendia --port=6000 # Uses 6000 (WebSocket) + 6001 (HTTP)
|
||||||
|
npx opendia --ws-port=5555 --http-port=5556 # Specify individually
|
||||||
|
|
||||||
|
# Handle port conflicts
|
||||||
|
# Note: Existing OpenDia processes are automatically terminated on startup
|
||||||
|
```
|
||||||
|
|
||||||
|
### Auto-Tunnel Mode
|
||||||
|
```bash
|
||||||
|
npx opendia --tunnel
|
||||||
|
```
|
||||||
|
- Automatically creates ngrok tunnel
|
||||||
|
- Copy URL for ChatGPT/online AI services
|
||||||
|
- Local functionality preserved
|
||||||
|
|
||||||
|
**Note**: For auto-tunneling to work, you need ngrok installed:
|
||||||
|
|
||||||
|
**macOS:**
|
||||||
|
```bash
|
||||||
|
brew install ngrok
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
```bash
|
||||||
|
# Using Chocolatey
|
||||||
|
choco install ngrok
|
||||||
|
|
||||||
|
# Or download from https://ngrok.com/download
|
||||||
|
```
|
||||||
|
|
||||||
|
**Linux:**
|
||||||
|
```bash
|
||||||
|
# Ubuntu/Debian
|
||||||
|
curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null
|
||||||
|
echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | sudo tee /etc/apt/sources.list.d/ngrok.list
|
||||||
|
sudo apt update && sudo apt install ngrok
|
||||||
|
|
||||||
|
# Or download from https://ngrok.com/download
|
||||||
|
```
|
||||||
|
|
||||||
|
Then get your free authtoken from https://dashboard.ngrok.com/get-started/your-authtoken and run:
|
||||||
|
```bash
|
||||||
|
ngrok config add-authtoken YOUR_TOKEN_HERE
|
||||||
|
```
|
||||||
|
|
||||||
## 🛠️ Capabilities
|
## 🛠️ Capabilities
|
||||||
|
|
||||||
OpenDia gives AI models **17 powerful browser tools**:
|
OpenDia gives AI models **18 powerful browser tools**:
|
||||||
|
|
||||||
### 🎯 Smart Page Understanding
|
### 🎯 Smart Page Understanding
|
||||||
- **Analyze any webpage** - AI automatically finds buttons, forms, and interactive elements
|
- **Analyze any webpage** - AI automatically finds buttons, forms, and interactive elements
|
||||||
@@ -127,6 +194,13 @@ OpenDia gives AI models **17 powerful browser tools**:
|
|||||||
- **Natural interactions** - Mimics human behavior to avoid triggering security measures
|
- **Natural interactions** - Mimics human behavior to avoid triggering security measures
|
||||||
- **Reliable automation** - Works consistently even on sites that block typical automation tools
|
- **Reliable automation** - Works consistently even on sites that block typical automation tools
|
||||||
|
|
||||||
|
### 🎨 Page Styling & Customization
|
||||||
|
- **Transform any website** - Apply fun themes, custom colors, and visual effects
|
||||||
|
- **Preset themes** - Dark hacker, retro 80s, rainbow party, minimalist zen, and more
|
||||||
|
- **AI mood styling** - Describe a mood and get matching visual design
|
||||||
|
- **Interactive effects** - Matrix rain, floating particles, neon glow, and cursor trails
|
||||||
|
- **Accessibility themes** - High contrast and readable designs for better visibility
|
||||||
|
|
||||||
## 💬 Example Prompts to Try
|
## 💬 Example Prompts to Try
|
||||||
|
|
||||||
Once everything is set up, try asking your AI:
|
Once everything is set up, try asking your AI:
|
||||||
@@ -149,6 +223,15 @@ Once everything is set up, try asking your AI:
|
|||||||
**Personal Assistant:**
|
**Personal Assistant:**
|
||||||
> *"Find that GitHub repo I was looking at yesterday about React components and bookmark it for later"*
|
> *"Find that GitHub repo I was looking at yesterday about React components and bookmark it for later"*
|
||||||
|
|
||||||
|
**Page Styling & Fun:**
|
||||||
|
> *"Apply a dark hacker theme to this page to make it look more interesting"*
|
||||||
|
|
||||||
|
> *"Make this boring documentation page feel like a cozy coffee shop"*
|
||||||
|
|
||||||
|
> *"Add some matrix rain effects to this page for 30 seconds for a cool screenshot"*
|
||||||
|
|
||||||
|
> *"Transform this page with a high contrast theme for better readability"*
|
||||||
|
|
||||||
## 🏗️ How It Works
|
## 🏗️ How It Works
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
@@ -190,6 +273,7 @@ npm start
|
|||||||
|
|
||||||
# Load extension in your browser
|
# Load extension in your browser
|
||||||
# Go to chrome://extensions/ → Developer mode → Load unpacked: ./opendia-extension
|
# Go to chrome://extensions/ → Developer mode → Load unpacked: ./opendia-extension
|
||||||
|
# Extension will auto-connect to server on localhost:5555
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ways to Contribute
|
### Ways to Contribute
|
||||||
|
|||||||
380
build-dxt.sh
Executable file
380
build-dxt.sh
Executable file
@@ -0,0 +1,380 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# OpenDia DXT Build Script - Fixed Version
|
||||||
|
# Run this from the OpenDia project root directory
|
||||||
|
|
||||||
|
set -e # Exit on any error
|
||||||
|
|
||||||
|
echo "🚀 Building OpenDia DXT package..."
|
||||||
|
|
||||||
|
# Check if we're in the right directory
|
||||||
|
if [ ! -f "opendia-mcp/package.json" ]; then
|
||||||
|
echo "❌ Error: Please run this script from the OpenDia project root directory"
|
||||||
|
echo " Expected to find: opendia-mcp/package.json"
|
||||||
|
echo " Current directory: $(pwd)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "opendia-extension" ]; then
|
||||||
|
echo "❌ Error: opendia-extension directory not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean and create dist directory
|
||||||
|
echo "🧹 Cleaning previous build..."
|
||||||
|
rm -rf dist
|
||||||
|
mkdir -p dist/opendia-dxt
|
||||||
|
|
||||||
|
echo "📦 Setting up package..."
|
||||||
|
|
||||||
|
# Copy server files
|
||||||
|
cp opendia-mcp/server.js dist/opendia-dxt/
|
||||||
|
|
||||||
|
# Create optimized package.json for DXT
|
||||||
|
cat > dist/opendia-dxt/package.json << 'EOF'
|
||||||
|
{
|
||||||
|
"name": "opendia",
|
||||||
|
"version": "1.0.5",
|
||||||
|
"description": "🎯 OpenDia - The open alternative to Dia. Connect your browser to AI models with anti-detection bypass for Twitter/X, LinkedIn, Facebook",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node server.js"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"mcp",
|
||||||
|
"browser",
|
||||||
|
"automation",
|
||||||
|
"ai",
|
||||||
|
"claude",
|
||||||
|
"chrome",
|
||||||
|
"extension",
|
||||||
|
"twitter",
|
||||||
|
"linkedin",
|
||||||
|
"facebook",
|
||||||
|
"anti-detection",
|
||||||
|
"dxt"
|
||||||
|
],
|
||||||
|
"author": "Aaron Elijah Mars <aaronjmars@proton.me>",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"express": "^4.21.2",
|
||||||
|
"ws": "^8.18.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
echo "⬇️ Installing dependencies..."
|
||||||
|
cd dist/opendia-dxt
|
||||||
|
npm install --production --silent
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
# Copy browser extension
|
||||||
|
echo "🌐 Copying browser extension..."
|
||||||
|
cp -r opendia-extension dist/opendia-dxt/extension
|
||||||
|
|
||||||
|
# Copy logo/icon files for DXT - try multiple sources
|
||||||
|
echo "🎨 Copying logo files..."
|
||||||
|
LOGO_COPIED=false
|
||||||
|
|
||||||
|
# Try different icon files from the extension
|
||||||
|
for icon_file in "icon-128.png" "icon-48.png" "icon-32.png" "icon-16.png" "icon.png"; do
|
||||||
|
if [ -f "opendia-extension/$icon_file" ]; then
|
||||||
|
cp "opendia-extension/$icon_file" dist/opendia-dxt/icon.png
|
||||||
|
echo "✅ Logo copied from extension/$icon_file"
|
||||||
|
LOGO_COPIED=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# If no extension icon found, check root directory
|
||||||
|
if [ "$LOGO_COPIED" = false ]; then
|
||||||
|
for icon_file in "icon.png" "logo.png" "opendia.png"; do
|
||||||
|
if [ -f "$icon_file" ]; then
|
||||||
|
cp "$icon_file" dist/opendia-dxt/icon.png
|
||||||
|
echo "✅ Logo copied from $icon_file"
|
||||||
|
LOGO_COPIED=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create a simple placeholder if no icon found
|
||||||
|
if [ "$LOGO_COPIED" = false ]; then
|
||||||
|
echo "⚠️ No logo file found, you may need to add icon.png manually to dist/opendia-dxt/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create DXT manifest - CORRECT FORMAT BASED ON WORKING EXAMPLES
|
||||||
|
echo "📋 Creating DXT manifest..."
|
||||||
|
cat > dist/opendia-dxt/manifest.json << 'EOF'
|
||||||
|
{
|
||||||
|
"dxt_version": "0.1",
|
||||||
|
"name": "opendia",
|
||||||
|
"display_name": "OpenDia - Browser Automation",
|
||||||
|
"version": "1.0.5",
|
||||||
|
"description": "🎯 OpenDia - The open alternative to Dia. Connect your browser to AI models with anti-detection bypass for Twitter/X, LinkedIn, Facebook + universal automation",
|
||||||
|
"author": {
|
||||||
|
"name": "Aaron Elijah Mars",
|
||||||
|
"email": "aaronjmars@proton.me",
|
||||||
|
"url": "https://github.com/aaronjmars/opendia"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/aaronjmars/opendia",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": ["browser", "automation", "mcp", "ai", "claude", "chrome", "extension", "twitter", "linkedin", "facebook", "anti-detection"],
|
||||||
|
"icon": "icon.png",
|
||||||
|
"icons": {
|
||||||
|
"128": "icon.png"
|
||||||
|
},
|
||||||
|
|
||||||
|
"server": {
|
||||||
|
"type": "node",
|
||||||
|
"entry_point": "server.js",
|
||||||
|
"mcp_config": {
|
||||||
|
"command": "node",
|
||||||
|
"args": ["${__dirname}/server.js"],
|
||||||
|
"env": {
|
||||||
|
"NODE_ENV": "production",
|
||||||
|
"WS_PORT": "${user_config.ws_port}",
|
||||||
|
"HTTP_PORT": "${user_config.http_port}",
|
||||||
|
"ENABLE_TUNNEL": "${user_config.enable_tunnel}",
|
||||||
|
"SAFETY_MODE": "${user_config.safety_mode}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"user_config": {
|
||||||
|
"ws_port": {
|
||||||
|
"type": "number",
|
||||||
|
"title": "WebSocket Port",
|
||||||
|
"description": "Port for Chrome extension connection",
|
||||||
|
"default": 5555,
|
||||||
|
"minimum": 1024,
|
||||||
|
"maximum": 65535
|
||||||
|
},
|
||||||
|
"http_port": {
|
||||||
|
"type": "number",
|
||||||
|
"title": "HTTP Port",
|
||||||
|
"description": "Port for HTTP/SSE server",
|
||||||
|
"default": 5556,
|
||||||
|
"minimum": 1024,
|
||||||
|
"maximum": 65535
|
||||||
|
},
|
||||||
|
"enable_tunnel": {
|
||||||
|
"type": "boolean",
|
||||||
|
"title": "Auto-Tunnel",
|
||||||
|
"description": "Automatically create ngrok tunnel for online AI access (requires ngrok)",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"safety_mode": {
|
||||||
|
"type": "boolean",
|
||||||
|
"title": "Safety Mode",
|
||||||
|
"description": "Block write/edit tools (element_click, element_fill) by default",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"name": "page_analyze",
|
||||||
|
"description": "🔍 Analyze any tab without switching! Two-phase intelligent page analysis"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "page_extract_content",
|
||||||
|
"description": "📄 Extract content from any tab without switching!"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "element_click",
|
||||||
|
"description": "🖱️ Click elements with anti-detection bypass for social platforms"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "element_fill",
|
||||||
|
"description": "✏️ Fill forms with anti-detection bypass for Twitter/X, LinkedIn, Facebook"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "page_navigate",
|
||||||
|
"description": "🧭 Navigate to URLs with wait conditions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "page_wait_for",
|
||||||
|
"description": "⏳ Wait for elements or conditions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tab_create",
|
||||||
|
"description": "📱 Create single or multiple tabs with batch support"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tab_close",
|
||||||
|
"description": "❌ Close specific tab(s) by ID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tab_list",
|
||||||
|
"description": "📋 Get list of all open tabs with IDs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tab_switch",
|
||||||
|
"description": "🔄 Switch to specific tab by ID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "element_get_state",
|
||||||
|
"description": "🔍 Get detailed element state information"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_bookmarks",
|
||||||
|
"description": "📚 Get all bookmarks or search for specific ones"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "add_bookmark",
|
||||||
|
"description": "➕ Add new bookmark"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_history",
|
||||||
|
"description": "🕒 Search browser history with comprehensive filters"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_selected_text",
|
||||||
|
"description": "📝 Get selected text from any tab"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "page_scroll",
|
||||||
|
"description": "📜 Scroll any tab without switching"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "get_page_links",
|
||||||
|
"description": "🔗 Get all hyperlinks with smart filtering"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "page_style",
|
||||||
|
"description": "🎨 Transform page appearance with themes and effects"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"capabilities": {
|
||||||
|
"browser_automation": true,
|
||||||
|
"anti_detection": true,
|
||||||
|
"background_tabs": true,
|
||||||
|
"multi_tab_workflows": true,
|
||||||
|
"content_extraction": true,
|
||||||
|
"form_filling": true,
|
||||||
|
"social_media_posting": true,
|
||||||
|
"page_styling": true,
|
||||||
|
"bookmark_management": true,
|
||||||
|
"history_search": true,
|
||||||
|
"tab_management": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"requirements": {
|
||||||
|
"chrome_extension": {
|
||||||
|
"name": "OpenDia Browser Extension",
|
||||||
|
"description": "Required Chrome extension for browser automation by Aaron Elijah Mars",
|
||||||
|
"version": "1.0.5",
|
||||||
|
"auto_install": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Validate JSON syntax
|
||||||
|
echo "🔍 Validating manifest.json..."
|
||||||
|
if ! python3 -m json.tool dist/opendia-dxt/manifest.json > /dev/null 2>&1; then
|
||||||
|
echo "❌ Error: Invalid JSON in manifest.json"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "✅ Manifest JSON is valid"
|
||||||
|
|
||||||
|
# Copy documentation
|
||||||
|
echo "📝 Adding documentation..."
|
||||||
|
cp README.md dist/opendia-dxt/ 2>/dev/null || echo "⚠️ README.md not found, skipping"
|
||||||
|
cp LICENSE dist/opendia-dxt/ 2>/dev/null || echo "⚠️ LICENSE not found, skipping"
|
||||||
|
|
||||||
|
# Create extension installation guide
|
||||||
|
cat > dist/opendia-dxt/EXTENSION_INSTALL.md << 'EOF'
|
||||||
|
# OpenDia Chrome Extension Installation
|
||||||
|
|
||||||
|
## Quick Setup
|
||||||
|
|
||||||
|
1. **Enable Developer Mode**
|
||||||
|
- Go to `chrome://extensions/`
|
||||||
|
- Toggle "Developer mode" in the top right
|
||||||
|
|
||||||
|
2. **Install Extension**
|
||||||
|
- Click "Load unpacked"
|
||||||
|
- Select the `extension/` folder from this DXT package
|
||||||
|
- Extension should appear in your extensions list
|
||||||
|
|
||||||
|
3. **Verify Connection**
|
||||||
|
- Click the OpenDia extension icon
|
||||||
|
- Should show "Connected to MCP server"
|
||||||
|
- Green status indicator means ready to use
|
||||||
|
|
||||||
|
## Supported Browsers
|
||||||
|
- Google Chrome, Arc Browser, Microsoft Edge, Brave Browser, Opera
|
||||||
|
- Any Chromium-based browser
|
||||||
|
|
||||||
|
## Features
|
||||||
|
🎯 Anti-detection bypass for Twitter/X, LinkedIn, Facebook
|
||||||
|
📱 Smart automation and page analysis
|
||||||
|
🔧 Form filling with enhanced compatibility
|
||||||
|
📊 Multi-tab workflows and background operations
|
||||||
|
🎨 Page styling and visual customization
|
||||||
|
|
||||||
|
For more help, visit: https://github.com/aaronjmars/opendia
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Verify structure before zipping
|
||||||
|
echo "🔍 Verifying DXT structure..."
|
||||||
|
echo "📋 Files in DXT directory:"
|
||||||
|
ls -la dist/opendia-dxt/
|
||||||
|
|
||||||
|
# Check if icon exists and show its details
|
||||||
|
if [ -f "dist/opendia-dxt/icon.png" ]; then
|
||||||
|
echo "✅ Icon file found:"
|
||||||
|
file dist/opendia-dxt/icon.png
|
||||||
|
ls -lh dist/opendia-dxt/icon.png
|
||||||
|
else
|
||||||
|
echo "❌ Icon file missing!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify manifest.json exists and is at root level
|
||||||
|
if [ ! -f "dist/opendia-dxt/manifest.json" ]; then
|
||||||
|
echo "❌ Error: manifest.json not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Structure verified"
|
||||||
|
|
||||||
|
# Create the DXT archive - CRITICAL: ZIP from inside the directory
|
||||||
|
echo "🗜️ Creating DXT archive..."
|
||||||
|
cd dist/opendia-dxt
|
||||||
|
zip -r ../opendia.dxt . -q
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
# Verify the DXT file structure
|
||||||
|
echo "🔍 Verifying DXT file contents..."
|
||||||
|
if ! unzip -l dist/opendia.dxt | grep -q "manifest.json"; then
|
||||||
|
echo "❌ Error: manifest.json not found in DXT file!"
|
||||||
|
echo "DXT contents:"
|
||||||
|
unzip -l dist/opendia.dxt
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get file size
|
||||||
|
DXT_SIZE=$(du -h dist/opendia.dxt | cut -f1)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ DXT package created successfully!"
|
||||||
|
echo "📦 File: dist/opendia.dxt"
|
||||||
|
echo "💾 Size: $DXT_SIZE"
|
||||||
|
echo ""
|
||||||
|
echo "📋 DXT Contents:"
|
||||||
|
unzip -l dist/opendia.dxt | head -10
|
||||||
|
echo ""
|
||||||
|
echo "🚀 Installation:"
|
||||||
|
echo "1. Double-click the .dxt file"
|
||||||
|
echo "2. Or: Claude Desktop Settings → Extensions → Install Extension"
|
||||||
|
echo "3. Install Chrome extension from extension/ folder"
|
||||||
|
echo ""
|
||||||
|
echo "🎯 Features ready: Anti-detection bypass + universal automation"
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -283,6 +283,13 @@ class BrowserAutomation {
|
|||||||
case "page_scroll":
|
case "page_scroll":
|
||||||
result = await this.scrollPage(data);
|
result = await this.scrollPage(data);
|
||||||
break;
|
break;
|
||||||
|
case "page_style":
|
||||||
|
result = await this.handlePageStyle(data);
|
||||||
|
break;
|
||||||
|
case "ping":
|
||||||
|
// Health check for background tab content script readiness
|
||||||
|
result = { status: "ready", timestamp: Date.now(), url: window.location.href };
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown action: ${action}`);
|
throw new Error(`Unknown action: ${action}`);
|
||||||
}
|
}
|
||||||
@@ -2503,7 +2510,375 @@ class BrowserAutomation {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🎨 Page Styling System
|
||||||
|
async handlePageStyle(data) {
|
||||||
|
const { mode, theme, background, text_color, font, font_size, mood, intensity, effect, duration, remember } = data;
|
||||||
|
|
||||||
|
// Remove existing custom styles
|
||||||
|
const existingStyle = document.getElementById('opendia-custom-style');
|
||||||
|
if (existingStyle) existingStyle.remove();
|
||||||
|
|
||||||
|
let css = '';
|
||||||
|
let description = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (mode) {
|
||||||
|
case 'preset':
|
||||||
|
const themeData = THEME_PRESETS[theme];
|
||||||
|
if (!themeData) throw new Error(`Unknown theme: ${theme}`);
|
||||||
|
css = themeData.css;
|
||||||
|
description = `Applied ${themeData.name} theme`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'custom':
|
||||||
|
css = this.buildCustomCSS({ background, text_color, font, font_size });
|
||||||
|
description = 'Applied custom styling';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'ai_mood':
|
||||||
|
css = this.generateMoodCSS(mood, intensity);
|
||||||
|
description = `Applied AI-generated style for mood: "${mood}"`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'effect':
|
||||||
|
css = this.applyEffect(effect, duration);
|
||||||
|
description = `Applied ${effect} effect for ${duration}s`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'reset':
|
||||||
|
// CSS already removed above
|
||||||
|
description = 'Reset page to original styling';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown styling mode: ${mode}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (css) {
|
||||||
|
const styleElement = document.createElement('style');
|
||||||
|
styleElement.id = 'opendia-custom-style';
|
||||||
|
styleElement.textContent = css;
|
||||||
|
document.head.appendChild(styleElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember preference if requested
|
||||||
|
if (remember && mode !== 'reset') {
|
||||||
|
const domain = window.location.hostname;
|
||||||
|
chrome.storage.local.set({ [`style_${domain}`]: { mode, theme, css } });
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
description,
|
||||||
|
applied_css: css.length,
|
||||||
|
mode,
|
||||||
|
theme: theme || 'custom',
|
||||||
|
remember_enabled: remember,
|
||||||
|
effect_duration: duration,
|
||||||
|
mood,
|
||||||
|
intensity
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: error.message,
|
||||||
|
mode,
|
||||||
|
theme,
|
||||||
|
applied_css: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildCustomCSS({ background, text_color, font, font_size }) {
|
||||||
|
let css = '';
|
||||||
|
|
||||||
|
if (background || text_color || font || font_size) {
|
||||||
|
css += '* { ';
|
||||||
|
if (background) css += `background: ${background} !important; `;
|
||||||
|
if (text_color) css += `color: ${text_color} !important; `;
|
||||||
|
if (font) css += `font-family: ${font} !important; `;
|
||||||
|
if (font_size) css += `font-size: ${font_size} !important; `;
|
||||||
|
css += '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
return css;
|
||||||
|
}
|
||||||
|
|
||||||
|
generateMoodCSS(mood, intensity) {
|
||||||
|
const moodMap = {
|
||||||
|
'cozy coffee shop': {
|
||||||
|
background: '#2c1810',
|
||||||
|
text: '#f4e4bc',
|
||||||
|
accent: '#d4af37',
|
||||||
|
font: 'Georgia, serif'
|
||||||
|
},
|
||||||
|
'energetic': {
|
||||||
|
background: 'linear-gradient(45deg, #ff6b35, #f7931e)',
|
||||||
|
text: '#ffffff',
|
||||||
|
effects: 'animation: energyPulse 1s infinite;'
|
||||||
|
},
|
||||||
|
'calm ocean': {
|
||||||
|
background: 'linear-gradient(to bottom, #87ceeb, #4682b4)',
|
||||||
|
text: '#ffffff',
|
||||||
|
effects: 'animation: gentleWave 4s ease-in-out infinite;'
|
||||||
|
},
|
||||||
|
'dark professional': {
|
||||||
|
background: '#1a1a1a',
|
||||||
|
text: '#e0e0e0',
|
||||||
|
accent: '#0066cc'
|
||||||
|
},
|
||||||
|
'warm sunset': {
|
||||||
|
background: 'linear-gradient(to bottom, #ff7e5f, #feb47b)',
|
||||||
|
text: '#ffffff'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const style = moodMap[mood.toLowerCase()] || moodMap['cozy coffee shop'];
|
||||||
|
return this.buildMoodCSS(style, intensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
buildMoodCSS(style, intensity) {
|
||||||
|
const opacity = intensity === 'subtle' ? '0.3' : intensity === 'medium' ? '0.6' : '0.9';
|
||||||
|
|
||||||
|
let css = `
|
||||||
|
body {
|
||||||
|
background: ${style.background} !important;
|
||||||
|
color: ${style.text} !important;
|
||||||
|
${style.font ? `font-family: ${style.font} !important;` : ''}
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
color: ${style.text} !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: ${style.accent || style.text} !important;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (style.effects) {
|
||||||
|
css += style.effects;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add animation keyframes if needed
|
||||||
|
if (style.effects && style.effects.includes('energyPulse')) {
|
||||||
|
css += `
|
||||||
|
@keyframes energyPulse {
|
||||||
|
0%, 100% { filter: hue-rotate(0deg); }
|
||||||
|
50% { filter: hue-rotate(180deg); }
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (style.effects && style.effects.includes('gentleWave')) {
|
||||||
|
css += `
|
||||||
|
@keyframes gentleWave {
|
||||||
|
0%, 100% { background-position: 0% 50%; }
|
||||||
|
50% { background-position: 100% 50%; }
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return css;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyEffect(effect, duration) {
|
||||||
|
const effects = {
|
||||||
|
matrix_rain: `
|
||||||
|
body::after {
|
||||||
|
content: '';
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y="10" font-size="8" fill="%2300ff00">0</text><text y="20" font-size="8" fill="%2300ff00">1</text><text y="30" font-size="8" fill="%2300ff00">0</text><text y="40" font-size="8" fill="%2300ff00">1</text></svg>');
|
||||||
|
animation: matrixFall 2s linear infinite;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 9999;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
@keyframes matrixFall {
|
||||||
|
from { transform: translateY(-100px); }
|
||||||
|
to { transform: translateY(100vh); }
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
floating_particles: `
|
||||||
|
body::before {
|
||||||
|
content: '✨ 🌟 ⭐ 💫';
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
animation: floatParticles 6s ease-in-out infinite;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 9999;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
@keyframes floatParticles {
|
||||||
|
0%, 100% { transform: translateY(100vh) rotate(0deg); }
|
||||||
|
50% { transform: translateY(-100px) rotate(180deg); }
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
cursor_trail: `
|
||||||
|
body {
|
||||||
|
cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"><circle cx="10" cy="10" r="8" fill="rgba(255,0,255,0.5)"/></svg>'), auto !important;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
neon_glow: `
|
||||||
|
* {
|
||||||
|
text-shadow: 0 0 10px #00ffff, 0 0 20px #00ffff, 0 0 30px #00ffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a, button {
|
||||||
|
box-shadow: 0 0 15px #ff00ff !important;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
typing_effect: `
|
||||||
|
* {
|
||||||
|
animation: typewriter 2s steps(40, end) infinite !important;
|
||||||
|
}
|
||||||
|
@keyframes typewriter {
|
||||||
|
from { width: 0; }
|
||||||
|
to { width: 100%; }
|
||||||
|
}
|
||||||
|
`
|
||||||
|
};
|
||||||
|
|
||||||
|
const css = effects[effect] || '';
|
||||||
|
|
||||||
|
// Auto-remove effect after duration
|
||||||
|
if (duration && duration > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
const effectStyle = document.getElementById('opendia-custom-style');
|
||||||
|
if (effectStyle) effectStyle.remove();
|
||||||
|
}, duration * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return css;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Theme Presets Database
|
||||||
|
const THEME_PRESETS = {
|
||||||
|
"dark_hacker": {
|
||||||
|
name: "🖤 Dark Hacker",
|
||||||
|
css: `
|
||||||
|
* {
|
||||||
|
background: #0a0a0a !important;
|
||||||
|
color: #00ff00 !important;
|
||||||
|
font-family: 'Courier New', monospace !important;
|
||||||
|
}
|
||||||
|
a { color: #00ffff !important; }
|
||||||
|
body::before {
|
||||||
|
content: ''; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
||||||
|
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y="50" font-size="10" fill="%23003300">01010101</text></svg>');
|
||||||
|
opacity: 0.1; pointer-events: none; z-index: -1;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
},
|
||||||
|
"retro_80s": {
|
||||||
|
name: "📼 Retro 80s",
|
||||||
|
css: `
|
||||||
|
* {
|
||||||
|
background: linear-gradient(45deg, #ff0080, #8000ff) !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
font-family: 'Arial Black', sans-serif !important;
|
||||||
|
text-shadow: 2px 2px 4px #000000 !important;
|
||||||
|
}
|
||||||
|
body { animation: retroPulse 2s infinite; }
|
||||||
|
@keyframes retroPulse { 0%, 100% { filter: hue-rotate(0deg); } 50% { filter: hue-rotate(180deg); } }
|
||||||
|
`
|
||||||
|
},
|
||||||
|
"rainbow_party": {
|
||||||
|
name: "🌈 Rainbow Party",
|
||||||
|
css: `
|
||||||
|
body {
|
||||||
|
background: linear-gradient(45deg, red, orange, yellow, green, blue, indigo, violet) !important;
|
||||||
|
background-size: 400% 400% !important;
|
||||||
|
animation: rainbowShift 3s ease infinite !important;
|
||||||
|
}
|
||||||
|
@keyframes rainbowShift {
|
||||||
|
0%, 100% { background-position: 0% 50%; }
|
||||||
|
50% { background-position: 100% 50%; }
|
||||||
|
}
|
||||||
|
* { color: white !important; text-shadow: 1px 1px 2px black !important; }
|
||||||
|
`
|
||||||
|
},
|
||||||
|
"minimalist_zen": {
|
||||||
|
name: "🧘 Minimalist Zen",
|
||||||
|
css: `
|
||||||
|
* {
|
||||||
|
background: #f8f8f8 !important;
|
||||||
|
color: #333333 !important;
|
||||||
|
font-family: 'Georgia', serif !important;
|
||||||
|
line-height: 1.6 !important;
|
||||||
|
}
|
||||||
|
body { max-width: 800px; margin: 0 auto; padding: 20px; }
|
||||||
|
`
|
||||||
|
},
|
||||||
|
"high_contrast": {
|
||||||
|
name: "🔍 High Contrast",
|
||||||
|
css: `
|
||||||
|
* {
|
||||||
|
background: #000000 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
font-family: Arial, sans-serif !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
a { color: #ffff00 !important; }
|
||||||
|
`
|
||||||
|
},
|
||||||
|
"cyberpunk": {
|
||||||
|
name: "🤖 Cyberpunk",
|
||||||
|
css: `
|
||||||
|
* {
|
||||||
|
background: #0d1117 !important;
|
||||||
|
color: #ff006e !important;
|
||||||
|
font-family: 'Courier New', monospace !important;
|
||||||
|
}
|
||||||
|
a { color: #00ffff !important; }
|
||||||
|
body {
|
||||||
|
background-image:
|
||||||
|
linear-gradient(90deg, transparent 79px, #abced4 79px, #abced4 81px, transparent 81px),
|
||||||
|
linear-gradient(#eee .1em, transparent .1em);
|
||||||
|
background-size: 81px 1.2em;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
},
|
||||||
|
"pastel_dream": {
|
||||||
|
name: "🌸 Pastel Dream",
|
||||||
|
css: `
|
||||||
|
* {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
|
||||||
|
color: #2c3e50 !important;
|
||||||
|
font-family: 'Comic Sans MS', cursive !important;
|
||||||
|
}
|
||||||
|
body { filter: sepia(20%) saturate(80%); }
|
||||||
|
`
|
||||||
|
},
|
||||||
|
"newspaper": {
|
||||||
|
name: "📰 Newspaper",
|
||||||
|
css: `
|
||||||
|
* {
|
||||||
|
background: #ffffff !important;
|
||||||
|
color: #000000 !important;
|
||||||
|
font-family: 'Times New Roman', serif !important;
|
||||||
|
line-height: 1.4 !important;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
column-count: 2;
|
||||||
|
column-gap: 2em;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Initialize the automation system
|
// Initialize the automation system
|
||||||
const browserAutomation = new BrowserAutomation();
|
const browserAutomation = new BrowserAutomation();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "OpenDia",
|
"name": "OpenDia",
|
||||||
"version": "1.0.0",
|
"version": "1.0.5",
|
||||||
"description": "Browser automation through Model Context Protocol",
|
"description": "Browser automation through Model Context Protocol",
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "icon-16.png",
|
"16": "icon-16.png",
|
||||||
|
|||||||
@@ -236,6 +236,80 @@
|
|||||||
button:active {
|
button:active {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.safety-mode {
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.8);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.safety-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.safety-label {
|
||||||
|
color: #374151;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.safety-toggle {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 50px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.safety-toggle input {
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.safety-slider {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #e5e7eb;
|
||||||
|
transition: 0.3s;
|
||||||
|
border-radius: 24px;
|
||||||
|
border: 1px solid rgba(0, 129, 247, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.safety-slider:before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
left: 2px;
|
||||||
|
bottom: 2px;
|
||||||
|
background-color: white;
|
||||||
|
transition: 0.3s;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .safety-slider {
|
||||||
|
background: linear-gradient(135deg, #0081F7, #1d4ed8);
|
||||||
|
border-color: rgba(0, 129, 247, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + .safety-slider:before {
|
||||||
|
transform: translateX(26px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.safety-slider:hover {
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -255,9 +329,9 @@
|
|||||||
<span id="statusText" class="tooltip">
|
<span id="statusText" class="tooltip">
|
||||||
Checking connection...
|
Checking connection...
|
||||||
<span class="tooltip-content">
|
<span class="tooltip-content">
|
||||||
Make sure your MCP server is connected.
|
Start server with: npx opendia
|
||||||
If it's the case, click on Reconnect.
|
Auto-discovery will find the correct ports.
|
||||||
If it still don't work, kill your 3000 port & try again.
|
Existing processes are automatically terminated on startup
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -265,7 +339,7 @@
|
|||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<span class="info-label">Server</span>
|
<span class="info-label">Server</span>
|
||||||
<span class="info-value" id="serverUrl">ws://localhost:3000</span>
|
<span class="info-value" id="serverUrl">Auto-Discovery</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<span class="info-label">Available Tools</span>
|
<span class="info-label">Available Tools</span>
|
||||||
@@ -277,6 +351,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="safety-mode">
|
||||||
|
<div class="safety-row">
|
||||||
|
<span class="safety-label tooltip">
|
||||||
|
Safety Mode
|
||||||
|
<span class="tooltip-content">
|
||||||
|
When enabled, blocks write/edit tools: element_click, element_fill
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<label class="safety-toggle">
|
||||||
|
<input type="checkbox" id="safetyMode">
|
||||||
|
<span class="safety-slider"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button id="reconnectBtn">Reconnect</button>
|
<button id="reconnectBtn">Reconnect</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ let statusIndicator = document.getElementById("statusIndicator");
|
|||||||
let statusText = document.getElementById("statusText");
|
let statusText = document.getElementById("statusText");
|
||||||
let toolCount = document.getElementById("toolCount");
|
let toolCount = document.getElementById("toolCount");
|
||||||
let currentPage = document.getElementById("currentPage");
|
let currentPage = document.getElementById("currentPage");
|
||||||
|
let serverUrl = document.getElementById("serverUrl");
|
||||||
|
|
||||||
// Get dynamic tool count from background script
|
// Get dynamic tool count from background script
|
||||||
function updateToolCount() {
|
function updateToolCount() {
|
||||||
@@ -59,16 +60,31 @@ function checkStatus() {
|
|||||||
checkStatus();
|
checkStatus();
|
||||||
setInterval(checkStatus, 2000);
|
setInterval(checkStatus, 2000);
|
||||||
|
|
||||||
|
// Update server URL display
|
||||||
|
function updateServerUrl() {
|
||||||
|
if (chrome.runtime?.id) {
|
||||||
|
chrome.runtime.sendMessage({ action: "getPorts" }, (response) => {
|
||||||
|
if (!chrome.runtime.lastError && response?.websocketUrl) {
|
||||||
|
serverUrl.textContent = response.websocketUrl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update server URL periodically
|
||||||
|
updateServerUrl();
|
||||||
|
setInterval(updateServerUrl, 5000);
|
||||||
|
|
||||||
// Update UI based on connection status
|
// Update UI based on connection status
|
||||||
function updateStatus(connected) {
|
function updateStatus(connected) {
|
||||||
if (connected) {
|
if (connected) {
|
||||||
statusIndicator.className = "status-indicator connected";
|
statusIndicator.className = "status-indicator connected";
|
||||||
statusText.innerHTML = `Connected to MCP server
|
statusText.innerHTML = `Connected to MCP server
|
||||||
<span class="tooltip-content">Make sure your MCP server is connected. If it's the case, click on Reconnect. If it still don't work, kill your 3000 port & try again.</span>`;
|
<span class="tooltip-content">Connected successfully! Server auto-discovery is working. Default ports: WebSocket=5555, HTTP=5556</span>`;
|
||||||
} else {
|
} else {
|
||||||
statusIndicator.className = "status-indicator disconnected";
|
statusIndicator.className = "status-indicator disconnected";
|
||||||
statusText.innerHTML = `Disconnected from MCP server
|
statusText.innerHTML = `Disconnected from MCP server
|
||||||
<span class="tooltip-content">Make sure your MCP server is connected. If it's the case, click on Reconnect. If it still don't work, kill your 3000 port & try again.</span>`;
|
<span class="tooltip-content">Start server with: npx opendia. Auto-discovery will find the correct ports. Existing processes are automatically terminated on startup</span>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +100,29 @@ document.getElementById("reconnectBtn").addEventListener("click", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Safety Mode Management
|
||||||
|
const safetyModeToggle = document.getElementById("safetyMode");
|
||||||
|
|
||||||
|
// Load safety mode state from storage
|
||||||
|
chrome.storage.local.get(['safetyMode'], (result) => {
|
||||||
|
const safetyEnabled = result.safetyMode || false; // Default to false (safety off)
|
||||||
|
safetyModeToggle.checked = safetyEnabled;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle safety mode toggle changes
|
||||||
|
safetyModeToggle.addEventListener('change', () => {
|
||||||
|
const safetyEnabled = safetyModeToggle.checked;
|
||||||
|
|
||||||
|
// Save to storage
|
||||||
|
chrome.storage.local.set({ safetyMode: safetyEnabled });
|
||||||
|
|
||||||
|
// Notify background script
|
||||||
|
chrome.runtime.sendMessage({
|
||||||
|
action: "setSafetyMode",
|
||||||
|
enabled: safetyEnabled
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Listen for updates from background script
|
// Listen for updates from background script
|
||||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
if (message.type === "statusUpdate") {
|
if (message.type === "statusUpdate") {
|
||||||
|
|||||||
208
opendia-mcp/README.md
Normal file
208
opendia-mcp/README.md
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
# OpenDia <img src="opendia-extension/icon-128.png" alt="OpenDia" width="32" height="32">
|
||||||
|
|
||||||
|
> **The open alternative to Dia**
|
||||||
|
> Connect your browser to AI models. No browser switching needed—works seamlessly with any Chromium browser including Chrome & Arc.
|
||||||
|
|
||||||
|
[](https://badge.fury.io/js/opendia)
|
||||||
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
## 📺 See it in Action
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 🚀 What is OpenDia?
|
||||||
|
|
||||||
|
OpenDia lets AI models control your browser automatically. **The key advantage? It leverages everything you already have**—your logged-in accounts, saved passwords, cookies, wallets, and browsing history. No need to start from scratch or switch contexts.
|
||||||
|
|
||||||
|
**🔑 Use Your Existing Digital Life:**
|
||||||
|
- ✅ **Logged-in accounts**: Post to Twitter / X, LinkedIn, Facebook with your existing sessions
|
||||||
|
- ✅ **Browser data**: Access your bookmarks, history, and saved passwords
|
||||||
|
- ✅ **Extensions & wallets**: Use MetaMask, password managers, or any installed extensions
|
||||||
|
- ✅ **Cookies & sessions**: Stay authenticated across all your favorite sites
|
||||||
|
- ✅ **Local testing**: Perfect for development with Cursor - test with real user sessions
|
||||||
|
|
||||||
|
**✨ Key Benefits:**
|
||||||
|
- 🔄 **Universal AI Support**: Works with Claude, ChatGPT, Cursor and even local models
|
||||||
|
- 🎯 **Anti-Detection**: Specialized bypasses for Twitter/X, LinkedIn, Facebook
|
||||||
|
- 📱 **Smart Automation**: AI understands your pages and finds the right elements
|
||||||
|
- 🛡️ **Privacy-First**: Everything runs locally, your data stays with you
|
||||||
|
- ⚡ **Zero Setup**: Get started with one command
|
||||||
|
|
||||||
|
## 🌐 Browser Support
|
||||||
|
|
||||||
|
Works with **any Chromium-based browser**:
|
||||||
|
- ✅ **Google Chrome**
|
||||||
|
- ✅ **Arc Browser**
|
||||||
|
- ✅ **Microsoft Edge**
|
||||||
|
- ✅ **Brave Browser**
|
||||||
|
- ✅ **Opera**
|
||||||
|
- ✅ **Vivaldi**
|
||||||
|
- ✅ **Any Chromium variant**
|
||||||
|
|
||||||
|
Perfect for **Cursor users** who want to automate their local testing and development workflows!
|
||||||
|
|
||||||
|
## 🎬 What You Can Do
|
||||||
|
|
||||||
|
**Real workflows you can try today:**
|
||||||
|
|
||||||
|
### 📰 Content & Social Media
|
||||||
|
- **"Summarize all the articles I read today and post a Twitter thread about the key insights"**
|
||||||
|
- **"Find interesting articles related to AI from my bookmarks and create a reading list"**
|
||||||
|
- **"Read this article and post a thoughtful comment on the LinkedIn version"**
|
||||||
|
- **"Check my recent Twitter bookmarks and summarize the main themes"**
|
||||||
|
|
||||||
|
### 📧 Productivity & Research
|
||||||
|
- **"Browse my latest emails and tell me what needs urgent attention"**
|
||||||
|
- **"Find all the GitHub repos I visited this week and create a summary report"**
|
||||||
|
- **"Extract the main points from this research paper and save them to my notes"**
|
||||||
|
- **"Search my browsing history for that article about AI safety I read last month"**
|
||||||
|
|
||||||
|
### 🤖 Development & Testing (Perfect for Cursor!)
|
||||||
|
- **"Test my web app's signup flow and take screenshots at each step"**
|
||||||
|
- **"Fill out this form with test data and check if validation works"**
|
||||||
|
- **"Navigate through my app and check if all the buttons work properly"**
|
||||||
|
- **"Use my connected wallet to test this DeFi interface"**
|
||||||
|
|
||||||
|
### 🔄 Advanced Automation
|
||||||
|
- **"Open tabs for all my daily news sources and summarize the top stories"**
|
||||||
|
- **"Draft replies to my unread messages based on the context"**
|
||||||
|
- **"Monitor this webpage and notify me when the content changes"**
|
||||||
|
- **"Automatically bookmark interesting articles I'm reading"**
|
||||||
|
|
||||||
|
## ⚡ Quick Start
|
||||||
|
|
||||||
|
### 1. Start the Server
|
||||||
|
```bash
|
||||||
|
npx opendia
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Install the Browser Extension
|
||||||
|
1. Download from [releases](https://github.com/aaronjmars/opendia/releases)
|
||||||
|
2. Go to `chrome://extensions/` (or your browser's extension page)
|
||||||
|
3. Enable "Developer mode"
|
||||||
|
4. Click "Load unpacked" and select the extension folder
|
||||||
|
|
||||||
|
### 3. Connect to Your AI
|
||||||
|
**For Claude Desktop**, add to your configuration:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"opendia": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["opendia"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**For Cursor or other AI tools**, use the same configuration or follow their specific setup instructions.
|
||||||
|
|
||||||
|
## 🛠️ Capabilities
|
||||||
|
|
||||||
|
OpenDia gives AI models **17 powerful browser tools**:
|
||||||
|
|
||||||
|
### 🎯 Smart Page Understanding
|
||||||
|
- **Analyze any webpage** - AI automatically finds buttons, forms, and interactive elements
|
||||||
|
- **Extract content intelligently** - Get clean text from articles, social posts, or search results
|
||||||
|
- **Understand context** - AI knows what type of page it's looking at and how to interact with it
|
||||||
|
|
||||||
|
### 🖱️ Natural Interactions
|
||||||
|
- **Click anything** - Buttons, links, menus - AI finds and clicks the right elements
|
||||||
|
- **Fill forms smartly** - Works even on complex sites like Twitter, LinkedIn, Facebook
|
||||||
|
- **Navigate seamlessly** - Go to pages, scroll, wait for content to load
|
||||||
|
- **Handle modern web apps** - Bypasses detection on social platforms
|
||||||
|
|
||||||
|
### 📑 Tab & Window Management
|
||||||
|
- **Multi-tab workflows** - Open, close, switch between tabs automatically
|
||||||
|
- **Organize your workspace** - Let AI manage your browser tabs efficiently
|
||||||
|
- **Coordinate complex tasks** - Work across multiple sites simultaneously
|
||||||
|
|
||||||
|
### 📊 Access Your Browser Data
|
||||||
|
- **Bookmarks & History** - Find that article you read last week
|
||||||
|
- **Current page content** - Get selected text, links, or full page content
|
||||||
|
- **Real-time information** - Work with whatever's currently on your screen
|
||||||
|
|
||||||
|
### 🛡️ Anti-Detection Features
|
||||||
|
- **Social media posting** - Bypass automation detection on Twitter/X, LinkedIn, Facebook
|
||||||
|
- **Natural interactions** - Mimics human behavior to avoid triggering security measures
|
||||||
|
- **Reliable automation** - Works consistently even on sites that block typical automation tools
|
||||||
|
|
||||||
|
## 💬 Example Prompts to Try
|
||||||
|
|
||||||
|
Once everything is set up, try asking your AI:
|
||||||
|
|
||||||
|
**Content Creation:**
|
||||||
|
> *"Read the article on this page and create a Twitter thread summarizing the main points"*
|
||||||
|
|
||||||
|
**Research & Analysis:**
|
||||||
|
> *"Look through my browser history from this week and find articles about machine learning. Summarize the key trends."*
|
||||||
|
|
||||||
|
**Social Media Management:**
|
||||||
|
> *"Check my Twitter bookmarks and organize them into categories. Create a summary of each category."*
|
||||||
|
|
||||||
|
**Productivity:**
|
||||||
|
> *"Open tabs for my usual morning reading sites and give me a briefing of today's top stories"*
|
||||||
|
|
||||||
|
**Development Testing:**
|
||||||
|
> *"Fill out this contact form with test data and check if the submission works properly"*
|
||||||
|
|
||||||
|
**Personal Assistant:**
|
||||||
|
> *"Find that GitHub repo I was looking at yesterday about React components and bookmark it for later"*
|
||||||
|
|
||||||
|
## 🏗️ How It Works
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph LR
|
||||||
|
A[AI Model] --> B[OpenDia Server]
|
||||||
|
B --> C[Browser Extension]
|
||||||
|
C --> D[Your Browser]
|
||||||
|
D --> E[Any Website]
|
||||||
|
```
|
||||||
|
|
||||||
|
1. **You ask** your AI to do something browser-related
|
||||||
|
2. **AI calls** OpenDia tools to understand and interact with pages
|
||||||
|
3. **OpenDia controls** your browser through the extension
|
||||||
|
4. **You get results** - AI can see what happened and respond intelligently
|
||||||
|
|
||||||
|
## 🔒 Security & Privacy
|
||||||
|
|
||||||
|
**Your data stays private**:
|
||||||
|
- ✅ **Everything runs locally** - No cloud processing of your browsing data
|
||||||
|
- ✅ **You control access** - Extension only works when you want it to
|
||||||
|
- ✅ **Open source** - Full transparency of what the code does
|
||||||
|
- ✅ **No tracking** - We don't collect or store any of your information
|
||||||
|
|
||||||
|
**Important**: This tool requires broad browser permissions to function. Only use with AI models you trust, and in environments where you're comfortable with browser automation.
|
||||||
|
|
||||||
|
## 🤝 Contributing
|
||||||
|
|
||||||
|
Love to have your help making OpenDia better!
|
||||||
|
|
||||||
|
### Quick Development Setup
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/aaronjmars/opendia.git
|
||||||
|
cd opendia
|
||||||
|
|
||||||
|
# Start the server
|
||||||
|
cd opendia-mcp
|
||||||
|
npm install
|
||||||
|
npm start
|
||||||
|
|
||||||
|
# Load extension in your browser
|
||||||
|
# Go to chrome://extensions/ → Developer mode → Load unpacked: ./opendia-extension
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ways to Contribute
|
||||||
|
- 🐛 **Report bugs** via [GitHub Issues](https://github.com/aaronjmars/opendia/issues)
|
||||||
|
- 💡 **Share it on social medias**
|
||||||
|
- 🔧 **Add new browser capabilities**
|
||||||
|
- 📖 **Improve documentation**
|
||||||
|
- 🧪 **Test with different AI models**
|
||||||
|
|
||||||
|
## 📝 License
|
||||||
|
|
||||||
|
MIT License - see [LICENSE](LICENSE) for details.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Ready to supercharge your browser with AI? Get started with `npx opendia`! 🚀**
|
||||||
44
opendia-mcp/package-lock.json
generated
44
opendia-mcp/package-lock.json
generated
@@ -1,15 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "opendia-server",
|
"name": "opendia",
|
||||||
"version": "1.0.0",
|
"version": "1.0.5",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "opendia-server",
|
"name": "opendia",
|
||||||
"version": "1.0.0",
|
"version": "1.0.5",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.x.x",
|
"cors": "^2.8.5",
|
||||||
"ws": "^8.x.x"
|
"express": "^4.21.2",
|
||||||
|
"ws": "^8.18.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"opendia": "server.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/accepts": {
|
"node_modules/accepts": {
|
||||||
@@ -78,7 +86,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/call-bound": {
|
"node_modules/call-bound": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
||||||
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -129,6 +137,19 @@
|
|||||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
|
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "2.6.9",
|
"version": "2.6.9",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
@@ -522,6 +543,15 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.13.4",
|
"version": "1.13.4",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||||
|
|||||||
@@ -1,13 +1,51 @@
|
|||||||
{
|
{
|
||||||
"name": "opendia-server",
|
"name": "opendia",
|
||||||
"version": "1.0.0",
|
"version": "1.0.5",
|
||||||
"description": "MCP Server for OpenDia Browser Bridge",
|
"description": "🎯 OpenDia - The open alternative to Dia. Connect your browser to AI models with anti-detection bypass for Twitter/X, LinkedIn, Facebook",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
|
"bin": {
|
||||||
|
"opendia": "./server.js"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js"
|
"start": "node server.js",
|
||||||
|
"tunnel": "node server.js --tunnel",
|
||||||
|
"sse-only": "node server.js --sse-only",
|
||||||
|
"tunnel-sse": "node server.js --tunnel --sse-only",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"mcp",
|
||||||
|
"browser",
|
||||||
|
"automation",
|
||||||
|
"ai",
|
||||||
|
"claude",
|
||||||
|
"chrome",
|
||||||
|
"extension",
|
||||||
|
"twitter",
|
||||||
|
"linkedin",
|
||||||
|
"facebook",
|
||||||
|
"anti-detection"
|
||||||
|
],
|
||||||
|
"author": "OpenDia Team",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/aaronjmars/opendia.git"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/aaronjmars/opendia",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/aaronjmars/opendia/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ws": "^8.x.x",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.x.x"
|
"express": "^4.21.2",
|
||||||
}
|
"ws": "^8.18.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"server.js",
|
||||||
|
"README.md"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
1491
opendia-mcp/server.js
Normal file → Executable file
1491
opendia-mcp/server.js
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
BIN
opendia.dxt
Normal file
BIN
opendia.dxt
Normal file
Binary file not shown.
Reference in New Issue
Block a user