Servidor MCP de segunda opinión
Un servidor MCP que brinda asistencia impulsada por IA para problemas de codificación combinando información de:
La inteligencia artificial Gemini de Google
Respuestas aceptadas por Stack Overflow
Análisis de IA de perplejidad
Características
Obtenga soluciones detalladas para problemas de codificación con contexto de múltiples fuentes
Detección automática del idioma a partir de las extensiones de archivo
Extracción y formato de fragmentos de código
Generación de informes de Markdown para soluciones
Recopilación del contexto de archivos compatible con Git
Related MCP server: Claude Code + Gemini MCP Server
Configuración
Instalar dependencias:
npm installConstruir el servidor:
npm run buildConfigurar variables de entorno en la configuración de MCP:
{
"mcpServers": {
"second-opinion": {
"command": "node",
"args": ["/path/to/second-opinion-server/build/index.js"],
"env": {
"GEMINI_API_KEY": "your-gemini-api-key",
"PERPLEXITY_API_KEY": "your-perplexity-api-key",
"STACK_EXCHANGE_KEY": "your-stack-exchange-key"
}
}
}
}Variables de entorno requeridas:
GEMINI_API_KEY: Clave de API de inteligencia artificial de Gemini de GooglePERPLEXITY_API_KEY: Clave de API de Perplexity AISTACK_EXCHANGE_KEY: Clave de API de Stack Exchange (opcional, utiliza acceso anónimo si no se proporciona)
Uso
El servidor proporciona una única herramienta:
obtener_una_segunda_opinión
Obtenga información y soluciones impulsadas por inteligencia artificial para problemas de codificación.
Esquema de entrada:
{
"goal": "string (required) - What you're trying to accomplish",
"error": "string (optional) - Any error messages you're seeing",
"code": "string (optional) - Relevant code context",
"solutionsTried": "string (optional) - What solutions you've already tried",
"filePath": "string (optional) - Path to the file with the issue"
}Ejemplo de entrada:
{
"goal": "Fix React useEffect cleanup error",
"error": "React Hook useEffect has a missing dependency: 'socket'. Either include it in the dependency array, or remove the dependency array react-hooks/exhaustive-deps",
"code": "useEffect(() => {\n socket.on('message', handleMessage);\n return () => socket.off('message');\n}, []);",
"solutionsTried": "I tried adding socket to the dependency array but then it causes infinite re-renders"
}Ejemplo de respuesta:
Entendiendo el problema
El problema principal radica en cómo el gancho useEffect de React gestiona los efectos secundarios y sus dependencias. Al proporcionar una matriz de dependencias vacía ( [] ), se le indica a React que el efecto solo debe ejecutarse una vez al montar el componente y que la función de limpieza debe ejecutarse al desmontarlo.
Sin embargo, en tu código, el objeto socket se usa dentro del efecto. Esto crea un cierre donde la función handleMessage y la función de limpieza ( socket.off('message') ) dependen implícitamente del valor actual de socket . Si socket cambia (por ejemplo, debido a una reconexión o reinicialización), tu efecto usará una instancia socket obsoleta.
Problemas comunes
Cierres obsoletos: el controlador de eventos (
handleMessage) podría estar funcionando con un objetosocketantiguoLimpieza incorrecta:
socket.off('message')podría no eliminar el detector de eventos previstoFugas de memoria: una limpieza fallida puede provocar fugas de memoria y un comportamiento inesperado.
Soluciones
1. Uso de useRef para referencias estables
import React, { useEffect, useRef } from 'react';
function MyComponent({ socket }) {
const socketRef = useRef(socket);
useEffect(() => {
const currentSocket = socketRef.current;
currentSocket.on('message', handleMessage);
return () => {
currentSocket.off('message');
};
}, []); // Empty dependency array is now safe
}Por qué funciona esto:
useRefcrea un objeto mutable que persiste entre representacionesEl objeto de referencia en sí no cambia, lo que evita que se vuelvan a ejecutar los efectos.
Puede acceder al último valor del socket a través de la referencia
2. Uso de useCallback para controladores
import React, { useEffect, useRef, useCallback } from 'react';
function MyComponent({ socket, someProp }) {
const socketRef = useRef(socket);
const handleMessage = useCallback((message) => {
// Do something with the message and potentially someProp
console.log(message, someProp);
}, [someProp]); // Include dependencies of handleMessage
useEffect(() => {
const currentSocket = socketRef.current;
currentSocket.on('message', handleMessage);
return () => {
currentSocket.off('message', handleMessage);
};
}, [handleMessage]); // Depend on the memoized handler
}3. Gestión del ciclo de vida del socket dentro de useEffect
import React, { useEffect, useState } from 'react';
function MyComponent() {
const [messages, setMessages] = useState([]);
useEffect(() => {
const socket = new WebSocket('your_websocket_url');
const handleMessage = (message) => {
setMessages((prevMessages) => [...prevMessages, message]);
};
socket.on('message', handleMessage);
return () => {
socket.off('message', handleMessage);
socket.close();
};
}, []); // Empty array is correct - socket lifecycle managed within
}4. Solución de gancho personalizada
function useSocket(url) {
const [messages, setMessages] = useState([]);
const socketRef = useRef(null);
useEffect(() => {
const socket = new WebSocket(url);
socketRef.current = socket;
const handleMessage = (message) => {
setMessages((prevMessages) => [...prevMessages, message]);
};
socket.on('message', handleMessage);
return () => {
socket.off('message', handleMessage);
socket.close();
};
}, [url]);
const sendMessage = useCallback((message) => {
if (socketRef.current?.readyState === WebSocket.OPEN) {
socketRef.current.send(message);
}
}, []);
return { messages, sendMessage };
}Mejores prácticas
Gestión de dependencias
Utilice
useRefpara referencias establesMemorizar controladores con
useCallbackConsidere la gestión del ciclo de vida del socket
Optimización del rendimiento
Minimizar las repeticiones de renderizado innecesarias
Manejar mensajes de gran volumen de manera eficiente
Utilice patrones de limpieza adecuados
Manejo de errores
Manejar errores de conexión con elegancia
Implementar la lógica de reconexión si es necesario
Limpiar los recursos adecuadamente
Consideraciones de prueba
Simular conexiones WebSocket en pruebas
Verificar la limpieza del detector de eventos
Escenarios de error de prueba
Estructura del proyecto
src/
├── config.ts # Configuration and API settings
├── fileUtils.ts # File operations and language detection
├── index.ts # Entry point
├── perplexity.ts # Perplexity AI integration
├── server.ts # MCP server implementation
├── stackOverflow.ts # Stack Overflow API integration
└── types.ts # TypeScript interfacesProblemas conocidos
Consulte errors.md para conocer problemas actuales y soluciones alternativas.