返回市场
二次意见MCP服务器

二次意见MCP服务器

作者:PoliTwit198415 星标更新:2025-01-10

项目介绍

第二意见 MCP 服务器

这是一个结合了以下资源提供的AI辅助编码问题解决方案的MCP服务器:

  • Google的Gemini AI
  • Stack Overflow被接受的答案
  • Perplexity 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密钥(可选,如果没有提供则使用匿名访问)

使用方法

该服务器提供了一个工具:

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钩子如何管理副作用及其依赖项。当您提供一个空的依赖数组([])时,您告诉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');
    };
  }, []); // 空的依赖数组现在是安全的
}

为什么这有效:

  • useRef创建了一个持久跨渲染的可变对象
  • 引用对象本身不会改变,防止效果重新运行
  • 您可以通过引用访问最新的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]); // 依赖于缓存的处理程序
}

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. 自定义钩子解决方案

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缓存处理程序
    • 考虑socket生命周期管理
  2. 性能优化

    • 最小化不必要的重新渲染
    • 高效地处理高容量的消息
    • 使用适当的清理模式
  3. 错误处理

    • 优雅地处理连接错误
    • 如需实现重连逻辑
    • 正确清理资源
  4. 测试考虑

    • 在测试中模拟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以了解当前的问题和解决方法。