Synthesizes insights from multiple AI sources to provide enhanced coding assistance with automatic language detection an...
Created byApr 23, 2025
Second Opinion MCP Server
An MCP server that provides AI-powered assistance for coding problems by combining insights from:
Google's Gemini AI
Stack Overflow accepted answers
Perplexity AI analysis
Features
Get detailed solutions for coding problems with context from multiple sources
Automatic language detection from file extensions
Code snippet extraction and formatting
Markdown report generation for solutions
Git-aware file context gathering
Setup
Install dependencies:
Build the server:
Configure environment variables in MCP settings:
Required environment variables:
GEMINI_API_KEY: Google's Gemini AI API key
PERPLEXITY_API_KEY: Perplexity AI API key
STACK_EXCHANGE_KEY: Stack Exchange API key (optional, uses anonymous access if not provided)
Usage
The server provides a single tool:
get_second_opinion
Get AI-powered insights and solutions for coding problems.
Input Schema:
Example Input:
Example Response:
Understanding the Problem
The core issue lies in how React's useEffect hook manages side effects and their dependencies. When you provide an empty dependency array ([]), you're telling React that the effect should only run once when the component mounts and that the cleanup function should run when the component unmounts.
However, in your code, the socket object is used within the effect. This creates a closure where the handleMessage function and the cleanup function (socket.off('message')) implicitly depend on the current value of socket. If socket ever changes (e.g., due to a reconnection or reinitialization), your effect will be using an outdated socket instance.
Common Issues
Stale Closures: The event handler (handleMessage) might be working with an old socket object
Incorrect Cleanup: The socket.off('message') might not remove the intended event listener
Memory Leaks: Failed cleanup can lead to memory leaks and unexpected behavior
Solutions
1. Using useRef for Stable References
Why This Works:
useRef creates a mutable object that persists across renders
The ref object itself doesn't change, preventing effect re-runs
You can access the latest socket value via the ref
2. Using useCallback for Handlers
3. Managing Socket Lifecycle Inside useEffect
4. Custom Hook Solution
Best Practices
Dependency Management
Performance Optimization
Error Handling
Testing Considerations
Project Structure
Known Issues
See errors.md for current issues and workarounds.
Second Opinion MCP Server
An MCP server that provides AI-powered assistance for coding problems by combining insights from:
Google's Gemini AI
Stack Overflow accepted answers
Perplexity AI analysis
Features
Get detailed solutions for coding problems with context from multiple sources
Automatic language detection from file extensions
Code snippet extraction and formatting
Markdown report generation for solutions
Git-aware file context gathering
Setup
Install dependencies:
Build the server:
Configure environment variables in MCP settings:
Required environment variables:
GEMINI_API_KEY: Google's Gemini AI API key
PERPLEXITY_API_KEY: Perplexity AI API key
STACK_EXCHANGE_KEY: Stack Exchange API key (optional, uses anonymous access if not provided)
Usage
The server provides a single tool:
get_second_opinion
Get AI-powered insights and solutions for coding problems.
Input Schema:
Example Input:
Example Response:
Understanding the Problem
The core issue lies in how React's useEffect hook manages side effects and their dependencies. When you provide an empty dependency array ([]), you're telling React that the effect should only run once when the component mounts and that the cleanup function should run when the component unmounts.
However, in your code, the socket object is used within the effect. This creates a closure where the handleMessage function and the cleanup function (socket.off('message')) implicitly depend on the current value of socket. If socket ever changes (e.g., due to a reconnection or reinitialization), your effect will be using an outdated socket instance.
Common Issues
Stale Closures: The event handler (handleMessage) might be working with an old socket object
Incorrect Cleanup: The socket.off('message') might not remove the intended event listener
Memory Leaks: Failed cleanup can lead to memory leaks and unexpected behavior
Solutions
1. Using useRef for Stable References
Why This Works:
useRef creates a mutable object that persists across renders
The ref object itself doesn't change, preventing effect re-runs
You can access the latest socket value via the ref