Major refactor: Multi-user Chrome MCP extension with remote server architecture
This commit is contained in:
243
test-direct-connection.js
Normal file
243
test-direct-connection.js
Normal file
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* Test script to validate the new direct connection architecture
|
||||
* This script tests:
|
||||
* 1. Remote server startup
|
||||
* 2. Chrome extension direct connection
|
||||
* 3. Tool call routing without native server
|
||||
*/
|
||||
|
||||
import fetch from 'node-fetch';
|
||||
import WebSocket from 'ws';
|
||||
|
||||
const REMOTE_SERVER_URL = 'http://localhost:3001';
|
||||
const CHROME_WS_URL = 'ws://localhost:3001/chrome';
|
||||
const MCP_HTTP_URL = 'http://localhost:3001/mcp';
|
||||
|
||||
console.log('🧪 Testing Direct Connection Architecture');
|
||||
console.log('==========================================');
|
||||
|
||||
// Test 1: Check if remote server is running
|
||||
async function testRemoteServerHealth() {
|
||||
console.log('\n1️⃣ Testing Remote Server Health...');
|
||||
try {
|
||||
const response = await fetch(`${REMOTE_SERVER_URL}/health`);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
console.log('✅ Remote server is running:', data);
|
||||
return true;
|
||||
} else {
|
||||
console.log('❌ Remote server health check failed:', response.status);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('❌ Remote server is not accessible:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test 2: Test MCP tools list via Streamable HTTP
|
||||
async function testMCPToolsList() {
|
||||
console.log('\n2️⃣ Testing MCP Tools List (Streamable HTTP)...');
|
||||
try {
|
||||
// Step 1: Initialize session
|
||||
const initResponse = await fetch(MCP_HTTP_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json, text/event-stream'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
jsonrpc: '2.0',
|
||||
id: 1,
|
||||
method: 'initialize',
|
||||
params: {
|
||||
protocolVersion: '2024-11-05',
|
||||
capabilities: {},
|
||||
clientInfo: { name: 'test-client', version: '1.0.0' }
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (!initResponse.ok) {
|
||||
throw new Error(`Init failed: ${initResponse.status}`);
|
||||
}
|
||||
|
||||
const sessionId = initResponse.headers.get('mcp-session-id');
|
||||
console.log('✅ MCP session initialized:', sessionId);
|
||||
|
||||
// Step 2: List tools
|
||||
const toolsResponse = await fetch(MCP_HTTP_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json, text/event-stream',
|
||||
'MCP-Session-ID': sessionId
|
||||
},
|
||||
body: JSON.stringify({
|
||||
jsonrpc: '2.0',
|
||||
id: 2,
|
||||
method: 'tools/list',
|
||||
params: {}
|
||||
})
|
||||
});
|
||||
|
||||
if (!toolsResponse.ok) {
|
||||
throw new Error(`Tools list failed: ${toolsResponse.status}`);
|
||||
}
|
||||
|
||||
const toolsData = await toolsResponse.text();
|
||||
console.log('✅ MCP tools list retrieved successfully');
|
||||
console.log('📋 Available tools count:', (toolsData.match(/chrome_/g) || []).length);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.log('❌ MCP tools list test failed:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Test 3: Test Chrome extension WebSocket connection
|
||||
async function testChromeExtensionConnection() {
|
||||
console.log('\n3️⃣ Testing Chrome Extension WebSocket Connection...');
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
const ws = new WebSocket(CHROME_WS_URL);
|
||||
let connected = false;
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
if (!connected) {
|
||||
console.log('❌ Chrome extension WebSocket connection timeout');
|
||||
ws.close();
|
||||
resolve(false);
|
||||
}
|
||||
}, 10000);
|
||||
|
||||
ws.on('open', () => {
|
||||
connected = true;
|
||||
clearTimeout(timeout);
|
||||
console.log('✅ Chrome extension WebSocket connected successfully');
|
||||
|
||||
// Test sending a message
|
||||
ws.send(JSON.stringify({
|
||||
id: 'test-123',
|
||||
action: 'ping',
|
||||
params: {}
|
||||
}));
|
||||
|
||||
setTimeout(() => {
|
||||
ws.close();
|
||||
resolve(true);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
ws.on('message', (data) => {
|
||||
console.log('📨 Received message from Chrome extension:', data.toString());
|
||||
});
|
||||
|
||||
ws.on('error', (error) => {
|
||||
clearTimeout(timeout);
|
||||
console.log('❌ Chrome extension WebSocket error:', error.message);
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
ws.on('close', () => {
|
||||
console.log('🔌 Chrome extension WebSocket connection closed');
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.log('❌ Chrome extension WebSocket test failed:', error.message);
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Test 4: Test tool call via MCP (simulating Cherry Studio)
|
||||
async function testToolCallViaMCP() {
|
||||
console.log('\n4️⃣ Testing Tool Call via MCP (Cherry Studio simulation)...');
|
||||
try {
|
||||
// Initialize session
|
||||
const initResponse = await fetch(MCP_HTTP_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json, text/event-stream'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
jsonrpc: '2.0',
|
||||
id: 1,
|
||||
method: 'initialize',
|
||||
params: {
|
||||
protocolVersion: '2024-11-05',
|
||||
capabilities: {},
|
||||
clientInfo: { name: 'test-client', version: '1.0.0' }
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const sessionId = initResponse.headers.get('mcp-session-id');
|
||||
|
||||
// Call a simple tool (get_windows_and_tabs)
|
||||
const toolCallResponse = await fetch(MCP_HTTP_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json, text/event-stream',
|
||||
'MCP-Session-ID': sessionId
|
||||
},
|
||||
body: JSON.stringify({
|
||||
jsonrpc: '2.0',
|
||||
id: 3,
|
||||
method: 'tools/call',
|
||||
params: {
|
||||
name: 'get_windows_and_tabs',
|
||||
arguments: {}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (toolCallResponse.ok) {
|
||||
const result = await toolCallResponse.text();
|
||||
console.log('✅ Tool call executed successfully');
|
||||
console.log('📊 Tool call result preview:', result.substring(0, 200) + '...');
|
||||
return true;
|
||||
} else {
|
||||
console.log('❌ Tool call failed:', toolCallResponse.status);
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('❌ Tool call test failed:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Run all tests
|
||||
async function runAllTests() {
|
||||
console.log('🚀 Starting Direct Connection Architecture Tests...\n');
|
||||
|
||||
const results = {
|
||||
serverHealth: await testRemoteServerHealth(),
|
||||
mcpToolsList: await testMCPToolsList(),
|
||||
chromeConnection: await testChromeExtensionConnection(),
|
||||
toolCall: await testToolCallViaMCP()
|
||||
};
|
||||
|
||||
console.log('\n📊 Test Results Summary:');
|
||||
console.log('========================');
|
||||
console.log(`Remote Server Health: ${results.serverHealth ? '✅ PASS' : '❌ FAIL'}`);
|
||||
console.log(`MCP Tools List: ${results.mcpToolsList ? '✅ PASS' : '❌ FAIL'}`);
|
||||
console.log(`Chrome Extension Connection: ${results.chromeConnection ? '✅ PASS' : '❌ FAIL'}`);
|
||||
console.log(`Tool Call Execution: ${results.toolCall ? '✅ PASS' : '❌ FAIL'}`);
|
||||
|
||||
const passCount = Object.values(results).filter(Boolean).length;
|
||||
const totalCount = Object.keys(results).length;
|
||||
|
||||
console.log(`\n🎯 Overall: ${passCount}/${totalCount} tests passed`);
|
||||
|
||||
if (passCount === totalCount) {
|
||||
console.log('🎉 All tests passed! Direct connection architecture is working correctly.');
|
||||
} else {
|
||||
console.log('⚠️ Some tests failed. Please check the remote server and Chrome extension setup.');
|
||||
}
|
||||
}
|
||||
|
||||
// Run the tests
|
||||
runAllTests().catch(console.error);
|
Reference in New Issue
Block a user