""" MCP Server for Second Opinion AI Agent Provides tools for analyzing ideas, detecting biases, and generating alternatives """ from mcp.server.fastmcp import FastMCP from pydantic import BaseModel, Field from typing import List, Dict, Optional, Literal import json from datetime import datetime # Initialize FastMCP server mcp = FastMCP("second-opinion-tools") class IdeaAnalysis(BaseModel): """Model for idea analysis input""" idea: str = Field(..., description="The idea or decision to analyze") context: Optional[str] = Field(None, description="Additional context or background") goals: Optional[List[str]] = Field(None, description="Stated goals or objectives") class BiasDetection(BaseModel): """Model for bias detection results""" bias_type: str description: str evidence: str severity: Literal["low", "medium", "high"] class Alternative(BaseModel): """Model for alternative solutions""" title: str description: str pros: List[str] cons: List[str] feasibility: Literal["low", "medium", "high"] @mcp.tool() def analyze_assumptions(idea: str, context: str = "") -> str: """ Analyzes an idea to identify hidden assumptions and unstated premises. Args: idea: The idea or decision to analyze context: Additional context or background information Returns: JSON string containing identified assumptions, their implications, and questions to verify them """ analysis = { "timestamp": datetime.now().isoformat(), "idea_summary": idea[:200] + "..." if len(idea) > 200 else idea, "analysis": { "explicit_assumptions": [ "Assumptions that are stated directly in the idea" ], "implicit_assumptions": [ "Assumptions that are implied but not stated", "Hidden premises that need to be examined" ], "foundational_beliefs": [ "Core beliefs this idea rests upon", "Worldview assumptions" ], "contextual_assumptions": [ "Assumptions about the environment", "Assumptions about timing and conditions" ] }, "verification_questions": [ "What evidence supports this assumption?", "What if this assumption is wrong?", "Under what conditions would this assumption fail?" ], "recommendations": [ "Test key assumptions before proceeding", "Identify which assumptions are most critical", "Create contingency plans for false assumptions" ] } return json.dumps(analysis, indent=2) @mcp.tool() def detect_cognitive_biases(idea: str, reasoning: str = "") -> str: """ Detects potential cognitive biases in reasoning and decision-making. Args: idea: The idea or decision being proposed reasoning: The reasoning or justification provided Returns: JSON string containing detected biases, their descriptions, and mitigation strategies """ common_biases = { "confirmation_bias": { "name": "Confirmation Bias", "description": "Tendency to search for or interpret information that confirms existing beliefs", "indicators": ["cherry-picking data", "ignoring contradictory evidence"], "severity": "high" }, "anchoring_bias": { "name": "Anchoring Bias", "description": "Over-reliance on the first piece of information encountered", "indicators": ["fixating on initial numbers", "difficulty adjusting from first impression"], "severity": "medium" }, "sunk_cost_fallacy": { "name": "Sunk Cost Fallacy", "description": "Continuing a course of action due to previously invested resources", "indicators": ["'we've come too far to turn back'", "justifying based on past investment"], "severity": "high" }, "availability_bias": { "name": "Availability Bias", "description": "Overestimating likelihood of events based on recent or memorable examples", "indicators": ["relying on anecdotes", "recent events driving decisions"], "severity": "medium" }, "optimism_bias": { "name": "Optimism Bias", "description": "Overestimating positive outcomes and underestimating risks", "indicators": ["'it won't happen to us'", "underestimating complexity"], "severity": "high" }, "groupthink": { "name": "Groupthink", "description": "Desire for harmony leads to poor decision-making", "indicators": ["suppressing dissent", "illusion of unanimity"], "severity": "high" } } analysis = { "timestamp": datetime.now().isoformat(), "detected_biases": list(common_biases.values()), "mitigation_strategies": [ "Actively seek disconfirming evidence", "Consult diverse perspectives", "Use pre-mortem analysis (imagine failure)", "Set decision criteria before gathering information", "Assign someone to play devil's advocate" ], "debiasing_questions": [ "What evidence would change my mind?", "Am I being overconfident?", "What am I not seeing?", "Would I make this decision if starting fresh today?" ] } return json.dumps(analysis, indent=2) @mcp.tool() def generate_alternatives( idea: str, constraints: str = "", num_alternatives: int = 5 ) -> str: """ Generates alternative approaches and solutions to consider. Args: idea: The original idea or approach constraints: Known constraints or requirements num_alternatives: Number of alternatives to generate (1-10) Returns: JSON string containing diverse alternative approaches with pros/cons analysis """ alternatives = { "original_idea": idea[:200] + "..." if len(idea) > 200 else idea, "constraints": constraints, "alternatives": [ { "id": 1, "title": "Incremental Approach", "description": "Break down the idea into smaller, testable steps", "pros": [ "Lower risk", "Learn as you go", "Can pivot based on feedback" ], "cons": [ "Slower to full implementation", "May lose momentum", "Partial solutions might not prove value" ], "feasibility": "high" }, { "id": 2, "title": "Opposite Approach", "description": "Consider doing the exact opposite of the proposed idea", "pros": [ "Reveals hidden assumptions", "May uncover better path", "Challenges conventional thinking" ], "cons": [ "May seem counterintuitive", "Requires reframing problem", "Not always applicable" ], "feasibility": "medium" }, { "id": 3, "title": "Hybrid Solution", "description": "Combine elements from multiple approaches", "pros": [ "Balances trade-offs", "Leverages strengths of each", "More flexible" ], "cons": [ "Can be complex", "May lack clear focus", "Harder to execute" ], "feasibility": "medium" }, { "id": 4, "title": "Wait and Learn", "description": "Delay decision while gathering more information", "pros": [ "Reduces uncertainty", "Market may validate/invalidate", "More data for better decision" ], "cons": [ "Opportunity cost", "Competitive disadvantage", "Analysis paralysis risk" ], "feasibility": "high" }, { "id": 5, "title": "Minimum Viable Approach", "description": "Find the simplest possible version that tests key assumptions", "pros": [ "Fast to implement", "Low resource commitment", "Quick validation" ], "cons": [ "May not fully represent vision", "Limited scope", "Could underestimate true potential" ], "feasibility": "high" } ][:num_alternatives], "evaluation_framework": { "criteria": [ "Alignment with goals", "Risk level", "Resource requirements", "Time to value", "Reversibility", "Learning potential" ], "process": "Score each alternative 1-10 on each criterion, then compare" } } return json.dumps(alternatives, indent=2) @mcp.tool() def perform_premortem_analysis(idea: str, timeframe: str = "1 year") -> str: """ Performs a pre-mortem analysis: imagine the idea failed and identify why. Args: idea: The idea or project to analyze timeframe: When in the future to imagine the failure (e.g., "6 months", "1 year") Returns: JSON string containing potential failure modes, warning signs, and preventive measures """ premortem = { "timestamp": datetime.now().isoformat(), "scenario": f"Imagine it's {timeframe} from now, and this idea has failed completely", "failure_modes": [ { "category": "Execution Failures", "scenarios": [ "Team lacked necessary skills", "Underestimated complexity and timeline", "Poor communication led to misalignment", "Key person left at critical moment" ] }, { "category": "Market/External Failures", "scenarios": [ "Market conditions changed unexpectedly", "Competitor launched better solution first", "Customer needs were misunderstood", "Regulatory changes blocked approach" ] }, { "category": "Strategic Failures", "scenarios": [ "Solving the wrong problem", "Solution didn't address root cause", "Opportunity cost was too high", "Failed to achieve minimum viable scale" ] }, { "category": "Resource Failures", "scenarios": [ "Ran out of budget before completion", "Couldn't secure necessary partnerships", "Technical infrastructure couldn't scale", "Dependencies failed or were delayed" ] } ], "early_warning_signs": [ "Metrics trending wrong direction", "Increasing resistance or skepticism", "Scope creep and deadline slips", "Key assumptions proving false", "Team morale declining" ], "preventive_measures": [ "Define clear success metrics upfront", "Build in checkpoints for go/no-go decisions", "Create contingency plans for top 3 risks", "Establish kill criteria before starting", "Schedule regular assumption testing" ], "questions_to_answer": [ "What would need to be true for this to succeed?", "What's our plan if X fails?", "How will we know if we're on the wrong path?", "What's our exit strategy?" ] } return json.dumps(premortem, indent=2) @mcp.tool() def identify_stakeholders_and_impacts( idea: str, organization_context: str = "" ) -> str: """ Identifies all stakeholders and analyzes potential impacts on each group. Args: idea: The idea or decision to analyze organization_context: Context about the organization or situation Returns: JSON string containing stakeholder analysis with impacts, concerns, and engagement strategies """ analysis = { "timestamp": datetime.now().isoformat(), "stakeholder_groups": [ { "group": "Direct Users/Customers", "impact_level": "high", "potential_impacts": [ "Changed user experience or workflow", "New learning curve required", "Value proposition shift" ], "likely_concerns": [ "Will this make things better or worse?", "How much effort to adapt?", "What if I don't like it?" ], "engagement_strategy": "Early involvement, clear communication, feedback loops" }, { "group": "Implementation Team", "impact_level": "high", "potential_impacts": [ "Additional workload", "New skills required", "Changed priorities" ], "likely_concerns": [ "Do we have capacity?", "What gets deprioritized?", "Is timeline realistic?" ], "engagement_strategy": "Involve in planning, realistic scoping, adequate resources" }, { "group": "Leadership/Decision Makers", "impact_level": "medium", "potential_impacts": [ "Resource allocation decisions", "Strategic direction implications", "Risk exposure" ], "likely_concerns": [ "What's the ROI?", "What are the risks?", "How does this fit strategy?" ], "engagement_strategy": "Business case, risk mitigation plan, metrics" }, { "group": "Adjacent Teams/Partners", "impact_level": "medium", "potential_impacts": [ "Workflow dependencies", "Integration requirements", "Coordination overhead" ], "likely_concerns": [ "How does this affect our work?", "What do we need to change?", "Were we consulted?" ], "engagement_strategy": "Early coordination, clear interfaces, collaborative planning" }, { "group": "Competitors/Market", "impact_level": "low", "potential_impacts": [ "Competitive dynamics shift", "Market expectations change", "Industry standards affected" ], "likely_concerns": [ "How to respond?", "Is this a threat or opportunity?" ], "engagement_strategy": "Market monitoring, strategic positioning" } ], "overlooked_stakeholders": [ "Consider: Who maintains this long-term?", "Consider: Who pays for this?", "Consider: Who gets blamed if it fails?", "Consider: Whose job becomes harder/easier?" ], "conflict_analysis": { "potential_conflicts": [ "Short-term costs vs long-term benefits", "Individual convenience vs collective good", "Innovation speed vs risk management" ], "resolution_approaches": [ "Transparent trade-off discussions", "Pilot programs to demonstrate value", "Phased rollout to manage change" ] } } return json.dumps(analysis, indent=2) @mcp.tool() def second_order_thinking(idea: str, time_horizon: str = "2-5 years") -> str: """ Analyzes second and third-order consequences of an idea or decision. Args: idea: The idea or decision to analyze time_horizon: Time period to consider for consequences Returns: JSON string containing cascade of consequences and system-level effects """ analysis = { "timestamp": datetime.now().isoformat(), "time_horizon": time_horizon, "consequence_cascade": { "first_order": { "description": "Immediate, direct effects", "examples": [ "Direct impact on users/customers", "Immediate resource requirements", "Initial results or outcomes" ] }, "second_order": { "description": "Effects of the first-order effects", "examples": [ "How do people adapt to the change?", "What new behaviors emerge?", "What dependencies are created?", "What gets easier/harder as a result?" ] }, "third_order": { "description": "Systemic shifts and long-term transformations", "examples": [ "How does culture or mindset shift?", "What new equilibrium is reached?", "What irreversible changes occur?", "What becomes possible/impossible?" ] } }, "unintended_consequences": { "positive": [ "Unexpected benefits that may emerge", "Side effects that create value elsewhere", "Learning and capability building" ], "negative": [ "Perverse incentives created", "Workarounds that undermine intent", "Dependencies that create fragility", "Race conditions or competitive dynamics" ] }, "feedback_loops": { "reinforcing": [ "What positive feedback loops could accelerate this?", "What could spiral out of control?" ], "balancing": [ "What natural limits exist?", "What forces will push back?" ] }, "questions_to_explore": [ "If this succeeds, then what?", "What happens when everyone does this?", "What does this make inevitable?", "What does this make obsolete?", "What new problems does this create?" ] } return json.dumps(analysis, indent=2) @mcp.tool() def opportunity_cost_analysis( idea: str, resources: str = "", alternatives: str = "" ) -> str: """ Analyzes opportunity costs: what you give up by choosing this path. Args: idea: The idea or decision being considered resources: Available resources (time, money, people, etc.) alternatives: Other options being considered Returns: JSON string containing opportunity cost analysis and trade-off framework """ analysis = { "timestamp": datetime.now().isoformat(), "core_concept": "Opportunity cost is what you give up when you choose one option over another", "resource_commitments": { "time": { "direct_time": "Time spent implementing this idea", "opportunity_cost": "What else could be done with that time?", "questions": [ "Is this the highest-value use of our time?", "What are we NOT doing by doing this?" ] }, "money": { "direct_cost": "Financial investment required", "opportunity_cost": "Alternative investments or savings", "questions": [ "What else could this money fund?", "What's the expected return compared to alternatives?" ] }, "attention": { "direct_cost": "Mental energy and focus required", "opportunity_cost": "Other priorities that get less attention", "questions": [ "What falls through the cracks?", "Where should attention be focused?" ] }, "reputation": { "direct_cost": "Credibility and social capital at stake", "opportunity_cost": "Political capital spent, trust consumed", "questions": [ "What if this fails publicly?", "Is this worth spending reputation on?" ] } }, "trade_off_framework": { "explicit_trade_offs": [ "What are we openly choosing to sacrifice?", "What constraints are we accepting?" ], "implicit_trade_offs": [ "What are we giving up without realizing it?", "What doors close by choosing this path?" ], "reversibility": [ "Can we undo this decision later?", "What becomes locked in?", "What optionality do we lose?" ] }, "better_alternatives_test": { "questions": [ "If we had unlimited time/money, would we still choose this?", "What would we do if this option didn't exist?", "Is there a 10x better option we're not seeing?", "Are we settling for local maximum?" ] }, "recommendations": [ "List out what you're explicitly NOT doing", "Quantify opportunity costs where possible", "Consider: is this a reversible decision?", "Ask: what keeps us from doing this AND something else?" ] } return json.dumps(analysis, indent=2) @mcp.tool() def red_team_analysis(idea: str, attack_surface: str = "") -> str: """ Performs red team analysis: actively tries to break or exploit the idea. Args: idea: The idea, system, or plan to attack attack_surface: Known vulnerabilities or areas of concern Returns: JSON string containing attack vectors, vulnerabilities, and defensive measures """ analysis = { "timestamp": datetime.now().isoformat(), "red_team_mindset": "Assume adversarial intent. How can this be broken, gamed, or exploited?", "attack_vectors": [ { "category": "Incentive Manipulation", "attacks": [ "How can users game the system?", "What perverse incentives does this create?", "How could metrics be manipulated?", "What loopholes exist?" ] }, { "category": "Technical Vulnerabilities", "attacks": [ "What breaks at scale?", "Where are single points of failure?", "What assumptions break under stress?", "What's the weakest link?" ] }, { "category": "Economic Attacks", "attacks": [ "How could competitors undermine this?", "What's the economic incentive to break it?", "How can value be extracted unfairly?", "What arbitrage opportunities exist?" ] }, { "category": "Social Engineering", "attacks": [ "How can trust be exploited?", "What social dynamics undermine intent?", "How can this be weaponized?", "What could go viral in bad ways?" ] }, { "category": "Edge Cases", "attacks": [ "What happens at extremes?", "What if 1000x more users?", "What if all users do X at once?", "What breaks the model?" ] } ], "defensive_measures": { "prevention": [ "Design out vulnerabilities", "Limit attack surface", "Build in circuit breakers", "Rate limiting and quotas" ], "detection": [ "Monitor for anomalies", "Set up alerts for abuse patterns", "Track leading indicators", "Regular security audits" ], "response": [ "Incident response plan", "Ability to roll back quickly", "Clear escalation paths", "Communication strategy" ] }, "worst_case_scenarios": [ "What's the absolute worst that could happen?", "How bad could this get before we notice?", "What if our assumptions are completely wrong?", "What if malicious actors target this?" ], "stress_test_questions": [ "What breaks first under pressure?", "Where is there no redundancy?", "What do we trust that we shouldn't?", "What could cascade into catastrophic failure?" ] } return json.dumps(analysis, indent=2) # Run the server if __name__ == "__main__": mcp.run()