@vectorchat/mcp-server
Version:
VectorChat MCP Server - Encrypted AI-to-AI communication with hardware security (YubiKey/TPM). 45+ MCP tools for Windsurf, Claude, and AI assistants. Model-based identity with EMDM encryption. Dynamic AI playbook system, communication zones, message relay
337 lines (282 loc) • 14.4 kB
JavaScript
// VectorChat Setup Wizard - Enhanced with Playwright, AI Guidance, and Background Model Download
let currentStep = 1;
const totalSteps = 7; // Added tutorial step
let modelDownloadInProgress = false;
let modelDownloadComplete = false;
let aiInstance = null; // Will hold the loaded Qwen 3 1.7B model
// ============================================================================
// STEP 1: Quick Setup with Tutorial
// ============================================================================
function quickSetup() {
const aiName = document.getElementById('aiName').value || 'Allicia';
const userName = document.getElementById('userName').value;
if (!userName) {
alert('Please enter your name');
return;
}
// Store values
window.setupConfig = {
aiName: aiName,
userName: userName,
modelType: 'qwen3-1.7b',
contextSize: 4096,
enableIPFS: false
};
// Start tutorial with background model download
startTutorialWithDownload();
}
function showAdvancedSetup() {
nextStep();
}
// ============================================================================
// TUTORIAL STEP: AI-Guided Setup with Background Download
// ============================================================================
function startTutorialWithDownload() {
// Hide step 1, show tutorial step
document.getElementById('step1').classList.remove('active');
currentStep = 2;
// Create tutorial step dynamically
const tutorialStep = document.createElement('div');
tutorialStep.className = 'step active';
tutorialStep.id = 'stepTutorial';
tutorialStep.innerHTML = `
<h2>🎓 VectorChat Tutorial</h2>
<p style="color: #666; margin-bottom: 20px;">
Let me walk you through VectorChat while we prepare your AI model in the background.
</p>
<div class="info-box">
<strong>📥 Background Activity:</strong>
<div id="downloadStatus" style="margin-top: 10px;">
<div style="display: flex; align-items: center; gap: 10px;">
<span id="downloadIcon">⏳</span>
<span id="downloadText">Starting Qwen 3 1.7B model download...</span>
</div>
<div id="downloadProgressContainer" style="margin-top: 10px; display: none;">
<div style="background: #f0f0f0; border-radius: 10px; overflow: hidden; height: 20px;">
<div id="downloadProgressBar" style="background: linear-gradient(90deg, #667eea, #764ba2); height: 100%; width: 0%; transition: width 0.3s;"></div>
</div>
<p id="downloadPercent" style="margin-top: 5px; text-align: center; font-size: 0.9em; color: #666;">0%</p>
</div>
</div>
</div>
<div id="tutorialContent" style="margin: 30px 0; padding: 20px; background: #f9f9f9; border-radius: 8px; min-height: 300px;">
<div id="tutorialStep1" class="tutorial-section">
<h3 style="color: #333; margin-bottom: 15px;">🚀 What is VectorChat?</h3>
<p style="color: #666; line-height: 1.6; margin-bottom: 15px;">
VectorChat is a secure AI communication platform that enables:
</p>
<ul style="margin-left: 20px; color: #666; line-height: 1.8;">
<li><strong>🤖 AI-to-AI Communication:</strong> Your AI can talk to other AIs securely</li>
<li><strong>🔐 EMDM Encryption:</strong> Model-based encryption with 496 trillion possible keys</li>
<li><strong>🌐 Decentralized:</strong> Uses IPFS for peer-to-peer communication</li>
<li><strong>⚡ Local-First:</strong> Your AI runs locally on your machine</li>
</ul>
<button class="primary" onclick="nextTutorialSection()" style="margin-top: 20px; width: 100%;">Continue →</button>
</div>
<div id="tutorialStep2" class="tutorial-section" style="display: none;">
<h3 style="color: #333; margin-bottom: 15px;">🤖 Your AI Assistant</h3>
<p style="color: #666; line-height: 1.6; margin-bottom: 15px;">
You've named your AI: <strong>${window.setupConfig.aiName}</strong>
</p>
<p style="color: #666; line-height: 1.6; margin-bottom: 15px;">
This AI will:
</p>
<ul style="margin-left: 20px; color: #666; line-height: 1.8;">
<li>Help you with tasks and questions</li>
<li>Communicate with other AIs in the network</li>
<li>Learn from your interactions</li>
<li>Respect your privacy with local-first processing</li>
</ul>
<p style="color: #666; margin-top: 15px;">
Your identity: <strong>${window.setupConfig.userName}</strong>
</p>
<button class="primary" onclick="nextTutorialSection()" style="margin-top: 20px; width: 100%;">Continue →</button>
</div>
<div id="tutorialStep3" class="tutorial-section" style="display: none;">
<h3 style="color: #333; margin-bottom: 15px;">🔐 Security & Privacy</h3>
<p style="color: #666; line-height: 1.6; margin-bottom: 15px;">
VectorChat uses advanced encryption:
</p>
<ul style="margin-left: 20px; color: #666; line-height: 1.8;">
<li><strong>EMDM Encryption:</strong> Keys derived from AI model weights</li>
<li><strong>Model Fingerprinting:</strong> Verify AI identity cryptographically</li>
<li><strong>Zero-Knowledge Proofs:</strong> Prove things without revealing data</li>
<li><strong>Local Processing:</strong> Your data never leaves your machine</li>
</ul>
<button class="primary" onclick="nextTutorialSection()" style="margin-top: 20px; width: 100%;">Continue →</button>
</div>
<div id="tutorialStep4" class="tutorial-section" style="display: none;">
<h3 style="color: #333; margin-bottom: 15px;">⚙️ Configuration</h3>
<p style="color: #666; line-height: 1.6; margin-bottom: 15px;">
Your setup includes:
</p>
<ul style="margin-left: 20px; color: #666; line-height: 1.8;">
<li><strong>Model:</strong> Qwen 3 1.7B (1.6 GB, optimized for speed)</li>
<li><strong>Context Size:</strong> 4096 tokens (balanced performance)</li>
<li><strong>Encryption:</strong> EMDM enabled (496T key space)</li>
<li><strong>Transport:</strong> WebSocket + IPFS ready</li>
</ul>
<p style="color: #666; margin-top: 15px; font-style: italic;">
You can customize these settings after setup if needed.
</p>
<button class="primary" onclick="completeTutorial()" style="margin-top: 20px; width: 100%;">Complete Setup →</button>
</div>
</div>
`;
// Insert tutorial step into wizard content
const wizardContent = document.querySelector('.wizard-content');
const allSteps = wizardContent.querySelectorAll('.step');
wizardContent.insertBefore(tutorialStep, allSteps[1]); // Insert after step 1
updateProgress();
// Start background model download
startBackgroundModelDownload();
}
let tutorialSectionIndex = 1;
function nextTutorialSection() {
const currentSection = document.getElementById(`tutorialStep${tutorialSectionIndex}`);
tutorialSectionIndex++;
const nextSection = document.getElementById(`tutorialStep${tutorialSectionIndex}`);
if (currentSection) currentSection.style.display = 'none';
if (nextSection) nextSection.style.display = 'block';
}
function completeTutorial() {
// Check if model download is complete
if (!modelDownloadComplete) {
alert('Model download is still in progress. Please wait...');
return;
}
// Move to configuration step
document.getElementById('stepTutorial').classList.remove('active');
currentStep = 3; // Skip to configuration
document.getElementById('step3').classList.add('active');
updateProgress();
}
// ============================================================================
// BACKGROUND MODEL DOWNLOAD
// ============================================================================
async function startBackgroundModelDownload() {
modelDownloadInProgress = true;
const downloadProgressContainer = document.getElementById('downloadProgressContainer');
const downloadProgressBar = document.getElementById('downloadProgressBar');
const downloadPercent = document.getElementById('downloadPercent');
const downloadText = document.getElementById('downloadText');
const downloadIcon = document.getElementById('downloadIcon');
downloadProgressContainer.style.display = 'block';
try {
// Simulate model download with progress
// In production, this would call the backend to download from IPFS
const response = await fetch('/api/download-model', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'qwen3-1.7b',
ipfsCid: 'QmXmPxxtLxtDgh4CYscgTDXyCbNfVWdzhG2UgS6fcX6mXS'
})
});
if (!response.ok) throw new Error('Download failed');
const reader = response.body.getReader();
let receivedLength = 0;
const totalLength = 1.6 * 1024 * 1024 * 1024; // 1.6 GB
while (true) {
const { done, value } = await reader.read();
if (done) break;
receivedLength += value.length;
const percentComplete = Math.round((receivedLength / totalLength) * 100);
downloadProgressBar.style.width = percentComplete + '%';
downloadPercent.textContent = percentComplete + '%';
downloadText.textContent = `Downloading Qwen 3 1.7B... ${percentComplete}%`;
}
// Download complete
modelDownloadComplete = true;
downloadIcon.textContent = '✅';
downloadText.textContent = 'Qwen 3 1.7B model ready!';
downloadProgressBar.style.width = '100%';
downloadPercent.textContent = '100%';
// Load the model
await loadAIModel();
} catch (error) {
console.error('Model download error:', error);
downloadIcon.textContent = '❌';
downloadText.textContent = 'Model download failed. You can continue with manual setup.';
modelDownloadInProgress = false;
}
}
async function loadAIModel() {
// In production, this would load the Qwen 3 1.7B model
// For now, we'll simulate it
console.log('Loading AI model...');
// aiInstance = await initializeQwen3Model();
}
// ============================================================================
// CONFIGURATION STEP
// ============================================================================
function updateProgress() {
// Adjust for tutorial step
let adjustedStep = currentStep;
if (currentStep > 2) adjustedStep = currentStep - 1; // Account for tutorial step
const progress = ((adjustedStep - 1) / (totalSteps - 1)) * 100;
document.getElementById('progressBar').style.width = progress + '%';
}
function nextStep() {
const currentStepEl = document.getElementById('step' + currentStep);
if (currentStepEl) {
currentStepEl.classList.remove('active');
}
currentStep++;
const nextStepEl = document.getElementById('step' + currentStep);
if (nextStepEl) {
nextStepEl.classList.add('active');
}
updateProgress();
}
function prevStep() {
const currentStepEl = document.getElementById('step' + currentStep);
if (currentStepEl) {
currentStepEl.classList.remove('active');
}
currentStep--;
const prevStepEl = document.getElementById('step' + currentStep);
if (prevStepEl) {
prevStepEl.classList.add('active');
}
updateProgress();
}
// ============================================================================
// APPLY CONFIGURATION & COMPLETE SETUP
// ============================================================================
async function applyConfiguration() {
const config = {
aiName: window.setupConfig.aiName,
userName: window.setupConfig.userName,
modelType: document.getElementById('modelType')?.value || 'qwen3-1.7b',
contextSize: document.getElementById('contextSize')?.value || 4096,
enableIPFS: document.getElementById('enableIPFS')?.checked || false,
mcpPort: document.getElementById('mcpPort')?.value || 8766,
wsPort: document.getElementById('wsPort')?.value || 8765
};
try {
const response = await fetch('/api/apply-config', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(config)
});
if (!response.ok) throw new Error('Configuration failed');
// Move to completion step
document.getElementById('step' + currentStep).classList.remove('active');
currentStep = totalSteps;
document.getElementById('step' + currentStep).classList.add('active');
updateProgress();
// Redirect to Flutter UI mirror after 2 seconds
setTimeout(() => {
window.location.href = '/ui';
}, 2000);
} catch (error) {
alert('Error applying configuration: ' + error.message);
}
}
// ============================================================================
// INITIALIZATION
// ============================================================================
window.addEventListener('load', () => {
updateProgress();
});