第二意见 MCP 服务器
MCP 服务器通过结合以下方面的见解,为编码问题提供 AI 驱动的帮助:
- 谷歌的Gemini AI
- Stack Overflow 接受的答案
- 困惑度AI分析
特征
- 从多个来源获取具有上下文的编码问题的详细解决方案
- 根据文件扩展名自动检测语言
- 代码片段提取和格式化
- 解决方案的 Markdown 报告生成
- Git 感知文件上下文收集
设置
- 安装依赖项:
- 构建服务器:
- 在 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"
}
}
}
}
所需的环境变量:
GEMINI_API_KEY
:Google 的 Gemini AI API 密钥PERPLEXITY_API_KEY
:Perplexity AI API 密钥STACK_EXCHANGE_KEY
:Stack Exchange API 密钥(可选,如果未提供则使用匿名访问)
用法
服务器提供一个单一工具:
获取第二意见
获取针对编码问题的人工智能见解和解决方案。
输入模式:
{
"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"
}
示例输入:
{
"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"
}
响应示例:
理解问题
核心问题在于 React 的useEffect
hook 如何管理副作用及其依赖项。当你提供一个空的依赖项数组 ( []
) 时,你是在告诉 React,该副作用只应在组件挂载时运行一次,而清理函数应在组件卸载时运行。
然而,在你的代码中,效果器内部使用了socket
对象。这会创建一个闭包,其中handleMessage
函数和清理函数 ( socket.off('message')
) 隐式依赖于socket
的当前值。如果socket
发生变化(例如,由于重新连接或重新初始化),你的效果器将使用过时的socket
实例。
常见问题
- **过时的闭包:**事件处理程序(
handleMessage
)可能正在使用旧的socket
对象 - 不正确的清理:
socket.off('message')
可能不会删除预期的事件监听器 - **内存泄漏:**清理失败可能导致内存泄漏和意外行为
解决方案
1. 使用 useRef 获得稳定引用
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
}
为什么有效:
useRef
创建一个可变对象,该对象在渲染过程中保持不变- ref 对象本身不会改变,从而防止 effect 重新运行
- 您可以通过 ref 访问最新的套接字值
2. 使用 useCallback 处理程序
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. 在 useEffect 中管理 Socket 生命周期
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. 自定义 Hook 解决方案
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 };
}
最佳实践
- 依赖管理
- 使用
useRef
获得稳定引用 - 使用
useCallback
来记忆处理程序 - 考虑套接字生命周期管理
- 性能优化
- 尽量减少不必要的重新渲染
- 高效处理大量消息
- 使用适当的清理模式
- 错误处理
- 妥善处理连接错误
- 如果需要,实现重新连接逻辑
- 正确清理资源
- 测试注意事项
- 在测试中模拟 WebSocket 连接
- 验证事件监听器清理
- 测试错误场景
项目结构
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 interfaces
已知问题
请参阅errors.md了解当前问题和解决方法。