Second Opinion MCP Server
利用谷歌 Gemini AI 提供 AI 驱动的编码问题协助,结合 Perplexity 的洞察和 Stack Overflow 的参考资料,促进上下文分析和自动响应存档,以改进故障排除。
README
Second Opinion MCP 服务器
一个 MCP 服务器,通过结合以下来源的见解,为编码问题提供 AI 驱动的辅助:
- Google 的 Gemini AI
- Stack Overflow 采纳的答案
- Perplexity AI 分析
功能
- 获取编码问题的详细解决方案,其中包含来自多个来源的上下文
- 从文件扩展名自动检测语言
- 代码片段提取和格式化
- 为解决方案生成 Markdown 报告
- Git 感知的文件上下文收集
设置
- 安装依赖项:
npm install
- 构建服务器:
npm run build
- 在 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 密钥(可选,如果未提供,则使用匿名访问)
用法
该服务器提供一个工具:
get_second_opinion
获取 AI 驱动的编码问题见解和解决方案。
输入模式:
{
"goal": "string (必需) - 您尝试完成的目标",
"error": "string (可选) - 您看到的任何错误消息",
"code": "string (可选) - 相关的代码上下文",
"solutionsTried": "string (可选) - 您已经尝试过的解决方案",
"filePath": "string (可选) - 出现问题的文件路径"
}
输入示例:
{
"goal": "修复 React useEffect 清理错误",
"error": "React Hook useEffect 缺少依赖项: 'socket'。 要么将其包含在依赖项数组中,要么删除依赖项数组 react-hooks/exhaustive-deps",
"code": "useEffect(() => {\n socket.on('message', handleMessage);\n return () => socket.off('message');\n}, []);",
"solutionsTried": "我尝试将 socket 添加到依赖项数组,但随后导致无限重新渲染"
}
响应示例:
理解问题
核心问题在于 React 的 useEffect
hook 如何管理副作用及其依赖项。 当您提供一个空依赖项数组 ([]
) 时,您是在告诉 React 该 effect 应该只在组件挂载时运行一次,并且清理函数应该在组件卸载时运行。
但是,在您的代码中,socket
对象在 effect 中使用。 这会创建一个闭包,其中 handleMessage
函数和清理函数 (socket.off('message')
) 隐式地依赖于 socket
的当前值。 如果 socket
发生更改(例如,由于重新连接或重新初始化),您的 effect 将使用过时的 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');
};
}, []); // 空依赖项数组现在是安全的
}
为什么有效:
useRef
创建一个在渲染之间持久存在的 mutable 对象- ref 对象本身不会改变,从而防止 effect 重新运行
- 您可以通过 ref 访问最新的 socket 值
2. 使用 useCallback 获取处理程序
import React, { useEffect, useRef, useCallback } from 'react';
function MyComponent({ socket, someProp }) {
const socketRef = useRef(socket);
const handleMessage = useCallback((message) => {
// 使用消息和潜在的 someProp 做一些事情
console.log(message, someProp);
}, [someProp]); // 包括 handleMessage 的依赖项
useEffect(() => {
const currentSocket = socketRef.current;
currentSocket.on('message', handleMessage);
return () => {
currentSocket.off('message', handleMessage);
};
}, [handleMessage]); // 依赖于 memoized 处理程序
}
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();
};
}, []); // 空数组是正确的 - socket 生命周期在内部管理
}
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
记忆处理程序 - 考虑 socket 生命周期管理
- 使用
-
性能优化
- 尽量减少不必要的重新渲染
- 有效处理大量消息
- 使用适当的清理模式
-
错误处理
- 优雅地处理连接错误
- 如果需要,实现重新连接逻辑
- 正确清理资源
-
测试注意事项
- 在测试中模拟 WebSocket 连接
- 验证事件侦听器清理
- 测试错误场景
项目结构
src/
├── config.ts # 配置和 API 设置
├── fileUtils.ts # 文件操作和语言检测
├── index.ts # 入口点
├── perplexity.ts # Perplexity AI 集成
├── server.ts # MCP 服务器实现
├── stackOverflow.ts # Stack Overflow API 集成
└── types.ts # TypeScript 接口
已知问题
请参阅 errors.md 了解当前问题和解决方法。
推荐服务器
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
mult-fetch-mcp-server
一个多功能的、符合 MCP 规范的网页内容抓取工具,支持多种模式(浏览器/Node)、格式(HTML/JSON/Markdown/文本)和智能代理检测,并提供双语界面(英语/中文)。
AIO-MCP Server
🚀 集成了 AI 搜索、RAG 和多服务(GitLab/Jira/Confluence/YouTube)的一体化 MCP 服务器,旨在增强 AI 驱动的开发工作流程。来自 Folk。
Hyperbrowser
欢迎来到 Hyperbrowser,人工智能的互联网。Hyperbrowser 是下一代平台,旨在增强人工智能代理的能力,并实现轻松、可扩展的浏览器自动化。它专为人工智能开发者打造,消除了本地基础设施和性能瓶颈带来的麻烦,让您能够:
https://github.com/Streen9/react-mcp
react-mcp 与 Claude Desktop 集成,能够根据用户提示创建和修改 React 应用程序。

any-chat-completions-mcp
将 Claude 与任何 OpenAI SDK 兼容的聊天完成 API 集成 - OpenAI、Perplexity、Groq、xAI、PyroPrompts 等。
Exa MCP Server
一个模型上下文协议服务器,它使像 Claude 这样的人工智能助手能够以安全和受控的方式,使用 Exa AI 搜索 API 执行实时网络搜索。
BigQuery MCP Server
这是一个服务器,可以让你的大型语言模型(LLM,比如Claude)直接与你的BigQuery数据对话!可以把它想象成一个友好的翻译器,它位于你的AI助手和数据库之间,确保它们可以安全高效地进行交流。