这是一个结合了以下资源提供的AI辅助编码问题解决方案的MCP服务器:
npm install
npm run build
{
"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密钥(可选,如果没有提供则使用匿名访问)该服务器提供了一个工具:
获取针对编码问题的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')可能没有删除预期的事件监听器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创建了一个持久跨渲染的可变对象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]); // 依赖于缓存的处理程序
}
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生命周期在内部管理
}
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缓存处理程序性能优化
错误处理
测试考虑
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以了解当前的问题和解决方法。