cd ~/mcp-platform/orchestrator

# Eliminar el archivo problemático
rm -f index.js

# Crear un archivo nuevo y limpio
cat > index.js << 'EOF'
import express from 'express';
import { spawn } from 'child_process';

const app = express();
app.use(express.json());

let scholarProcess = null;
let pendingRequests = new Map();

const BRAVE_API_KEY = "BSAcKz8Yw7wHwvrAtusBzmH3fvm52UM";
const BRAVE_SEARCH_URL = "https://api.search.brave.com/res/v1/web/search";

async function webSearch(query) {
    try {
        const url = new URL(BRAVE_SEARCH_URL);
        url.searchParams.append('q', query);
        url.searchParams.append('count', '10');
        
        const response = await fetch(url.toString(), {
            method: 'GET',
            headers: {
                'Accept': 'application/json',
                'X-Subscription-Token': BRAVE_API_KEY
            }
        });
        
        if (!response.ok) {
            throw new Error(`Brave API error: ${response.status}`);
        }
        
        const data = await response.json();
        let results = [];
        
        if (data.web && data.web.results) {
            results.push({ type: 'text', text: `Resultados para "${query}":` });
            for (const r of data.web.results.slice(0, 5)) {
                results.push({ type: 'text', text: `- ${r.title}: ${r.url}` });
            }
        }
        
        if (results.length === 0) {
            results.push({ type: 'text', text: `No se encontraron resultados para "${query}"` });
        }
        
        return { content: results };
    } catch (error) {
        throw new Error(`Web search failed: ${error.message}`);
    }
}

function initScholar() {
    if (scholarProcess) return;
    scholarProcess = spawn('docker', ['exec', '-i', 'scholar-mcp', 'scholar-mcp', 'serve']);
    
    let buffer = '';
    scholarProcess.stdout.on('data', (data) => {
        buffer += data.toString();
        const lines = buffer.split('\n');
        buffer = lines.pop() || '';
        for (const line of lines) {
            if (line.trim().startsWith('{')) {
                try {
                    const response = JSON.parse(line);
                    if (response.id && pendingRequests.has(response.id)) {
                        const cb = pendingRequests.get(response.id);
                        pendingRequests.delete(response.id);
                        if (response.result) cb.resolve(response.result);
                        else cb.reject(new Error(response.error?.message || 'Unknown error'));
                    }
                } catch(e) {}
            }
        }
    });
    
    scholarProcess.stderr.on('data', (data) => console.error('Scholar:', data.toString()));
    scholarProcess.on('close', () => {
        scholarProcess = null;
        setTimeout(initScholar, 2000);
    });
    
    const initMsg = JSON.stringify({
        jsonrpc: '2.0',
        method: 'initialize',
        params: { protocolVersion: '2025-11-25', capabilities: {}, clientInfo: { name: 'orchestrator', version: '1.0' } },
        id: 1
    }) + '\n';
    scholarProcess.stdin.write(initMsg);
}

function callScholar(toolName, args) {
    return new Promise((resolve, reject) => {
        if (!scholarProcess) {
            initScholar();
            setTimeout(() => callScholar(toolName, args).then(resolve).catch(reject), 1000);
            return;
        }
        const id = Date.now();
        pendingRequests.set(id, { resolve, reject });
        const request = JSON.stringify({
            jsonrpc: '2.0',
            method: 'tools/call',
            params: { name: toolName, arguments: args },
            id: id
        }) + '\n';
        scholarProcess.stdin.write(request);
        setTimeout(() => {
            if (pendingRequests.has(id)) {
                pendingRequests.delete(id);
                reject(new Error('Timeout'));
            }
        }, 60000);
    });
}

function callSureChEMBL(toolName, args) {
    return new Promise((resolve, reject) => {
        const proc = spawn('docker', ['exec', '-i', 'surechembl-mcp', 'node', 'build/index.js']);
        let output = '';
        proc.stdout.on('data', (data) => { output += data.toString(); });
        proc.on('close', (code) => {
            if (code !== 0) return reject(new Error('SureChEMBL failed'));
            try {
                const res = JSON.parse(output);
                resolve(res.result);
            } catch(e) { reject(e); }
        });
        proc.stdin.write(JSON.stringify({
            jsonrpc: '2.0',
            method: 'tools/call',
            params: { name: toolName, arguments: args },
            id: Date.now()
        }) + '\n');
        proc.stdin.end();
    });
}

initScholar();

app.post('/mcp', async (req, res) => {
    const { method, params, id } = req.body;
    console.log('Request:', method, id);
    
    if (method === 'tools/list') {
        return res.json({
            jsonrpc: '2.0',
            id: id,
            result: {
                tools: [
                    { name: 'ping', description: 'Pong' },
                    { name: 'search_patents', description: 'Search patents' },
                    { name: 'search_papers', description: 'Search papers' },
                    { name: 'web_search', description: 'Web search' },
                    { name: 'search_chemicals_by_name', description: 'Search chemicals' }
                ]
            }
        });
    }
    
    if (method === 'tools/call') {
        const name = params?.name;
        const args = params?.arguments || {};
        
        if (name === 'ping') {
            return res.json({ jsonrpc: '2.0', id: id, result: { content: [{ type: 'text', text: 'pong' }] } });
        }
        
        if (name === 'web_search') {
            try {
                const result = await webSearch(args.query);
                return res.json({ jsonrpc: '2.0', id: id, result });
            } catch (err) {
                return res.json({ jsonrpc: '2.0', id: id, result: { content: [{ type: 'text', text: 'Error: ' + err.message }], isError: true } });
            }
        }
        
        try {
            let result;
            if (name === 'search_patents' || name === 'search_papers') {
                result = await callScholar(name, args);
            } else if (name === 'search_chemicals_by_name') {
                result = await callSureChEMBL(name, args);
            } else {
                throw new Error('Unknown tool: ' + name);
            }
            return res.json({ jsonrpc: '2.0', id: id, result });
        } catch (err) {
            return res.json({ jsonrpc: '2.0', id: id, result: { content: [{ type: 'text', text: 'Error: ' + err.message }], isError: true } });
        }
    }
    
    res.json({ jsonrpc: '2.0', id: id, error: { code: -32600, message: 'Method not found' } });
});

app.get('/health', (req, res) => res.json({ status: 'ok' }));
app.listen(3000, '0.0.0.0', () => console.log('Server running on port 3000'));
EOF

# Verificar sintaxis
node -c index.js

# Reconstruir
cd ~/mcp-platform
docker compose build orchestrator --no-cache
docker compose up -d

# Probar
sleep 5
curl http://localhost:3000/health
curl -X POST http://localhost:3000/mcp -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"ping","arguments":{}},"id":1}'
curl -X POST http://localhost:3000/mcp -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"web_search","arguments":{"query":"artificial intelligence"}},"id":10}'