Second Opinion MCP Server

remote-capable server

The server can be hosted and run remotely because it primarily relies on remote services or has no dependency on the local environment.

Integrations

  • Uses git awareness to gather file context for better understanding of coding problems

  • Integrates with Google's Gemini AI to provide AI-powered assistance for coding problems

  • Integrates with Perplexity AI to provide analysis for coding solutions

第二意见 MCP 服务器

MCP 服务器通过结合以下方面的见解,为编码问题提供 AI 驱动的帮助:

  • 谷歌的Gemini AI
  • Stack Overflow 接受的答案
  • 困惑度AI分析

特征

  • 从多个来源获取具有上下文的编码问题的详细解决方案
  • 根据文件扩展名自动检测语言
  • 代码片段提取和格式化
  • 解决方案的 Markdown 报告生成
  • Git 感知文件上下文收集

设置

  1. 安装依赖项:
npm install
  1. 构建服务器:
npm run build
  1. 在 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 }; }

最佳实践

  1. 依赖管理
    • 使用useRef获得稳定引用
    • 使用useCallback来记忆处理程序
    • 考虑套接字生命周期管理
  2. 性能优化
    • 尽量减少不必要的重新渲染
    • 高效处理大量消息
    • 使用适当的清理模式
  3. 错误处理
    • 妥善处理连接错误
    • 如果需要,实现重新连接逻辑
    • 正确清理资源
  4. 测试注意事项
    • 在测试中模拟 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了解当前问题和解决方法。

-
security - not tested
F
license - not found
-
quality - not tested

使用 Google 的 Gemini AI 为编码问题提供人工智能帮助,结合 Perplexity 洞察和 Stack Overflow 参考,促进上下文分析和自动响应存档,从而改进故障排除。

  1. Features
    1. Setup
      1. Usage
        1. get_second_opinion
      2. Understanding the Problem
        1. Common Issues
      3. Solutions
        1. 1. Using useRef for Stable References
        2. 2. Using useCallback for Handlers
        3. 3. Managing Socket Lifecycle Inside useEffect
        4. 4. Custom Hook Solution
      4. Best Practices
        1. Project Structure
          1. Known Issues
            ID: klbxlpz1vu