"""
Citation Extractor - Text-Based MCP Server
===========================================
THIS is the correct architecture for Claude Desktop!

Instead of requiring file paths (machine-specific), this server accepts TEXT INPUT.
Claude can now use these tools on:
- Uploaded PDFs (Claude extracts text, passes to tool)
- Web content (Claude fetches, passes to tool)
- Any text Claude has access to in conversation

This makes it a universal booster for Claude's legal capabilities!
"""

import asyncio
import sys
from typing import Any, Sequence

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent

# Import our text-based extraction functions
from text_extraction_core import (
    extract_citations_from_text,
    extract_statutes_from_text,
    search_keywords_in_text,
    format_citations_output,
    format_statutes_output,
    format_keywords_output,
    analyze_text_comprehensive
)

# Import law school features (refactored to use text)
try:
    from legal_analysis import (
        format_case_citation_bluebook,
        generate_table_of_authorities,
        classify_jurisdiction,
        detect_standards_of_review,
        cluster_by_topic,
        identify_primary_topics,
        group_by_jurisdiction
    )
    LAW_FEATURES_AVAILABLE = True
except ImportError:
    LAW_FEATURES_AVAILABLE = False

try:
    from case_analysis import extract_case_brief
    CASE_ANALYSIS_AVAILABLE = True
except ImportError:
    CASE_ANALYSIS_AVAILABLE = False

try:
    from study_aids import generate_flash_cards_from_brief, format_flash_cards_anki, format_flash_cards_quizlet
    STUDY_AIDS_AVAILABLE = True
except ImportError:
    STUDY_AIDS_AVAILABLE = False

# Import advanced analysis tools
try:
    from advanced_analysis import (
        analyze_for_rules,
        analyze_for_arguments,
        analyze_for_facts,
        compare_two_cases,
        generate_memo,
        analyze_opposing
    )
    ADVANCED_ANALYSIS_AVAILABLE = True
except ImportError:
    ADVANCED_ANALYSIS_AVAILABLE = False

# Import enhanced citation analysis
try:
    from enhanced_citations import (
        analyze_citations_enhanced,
        get_citations_as_dict,
        extract_enhanced_citations
    )
    ENHANCED_CITATIONS_AVAILABLE = True
except ImportError:
    ENHANCED_CITATIONS_AVAILABLE = False

# Import enhanced rule analysis
try:
    from enhanced_rules import (
        analyze_rules_enhanced,
        get_rules_as_dict,
        extract_enhanced_rules
    )
    ENHANCED_RULES_AVAILABLE = True
except ImportError:
    ENHANCED_RULES_AVAILABLE = False

# Import legal document formatter
try:
    from legal_document_formatter import (
        create_legal_document,
        format_as_plain_text,
        export_memo_to_docx,
        parse_memo_sections,
        get_formatted_output,
        get_desktop_path,
        DOCX_AVAILABLE
    )
    DOCUMENT_FORMATTER_AVAILABLE = True
except ImportError:
    DOCUMENT_FORMATTER_AVAILABLE = False
    DOCX_AVAILABLE = False

# Import writing style analyzer
try:
    from writing_style import (
        analyze_writing_style,
        improve_legal_writing
    )
    WRITING_STYLE_AVAILABLE = True
except ImportError:
    WRITING_STYLE_AVAILABLE = False

# Import IRAC synthesis engine
try:
    from irac_synthesis import (
        generate_irac_draft,
        rank_authorities
    )
    IRAC_SYNTHESIS_AVAILABLE = True
except ImportError:
    IRAC_SYNTHESIS_AVAILABLE = False

# Import argument weakness detector
try:
    from argument_weakness import (
        analyze_weaknesses_formatted,
        get_weakness_data,
        analyze_argument_weaknesses,
        format_weakness_report,
        LitigationStage
    )
    ARGUMENT_WEAKNESS_AVAILABLE = True
except ImportError:
    ARGUMENT_WEAKNESS_AVAILABLE = False

# Import batch processing
try:
    from batch_processing import (
        batch_analyze_formatted,
        get_batch_data,
        find_common_authorities
    )
    BATCH_PROCESSING_AVAILABLE = True
except ImportError:
    BATCH_PROCESSING_AVAILABLE = False

# Import OCR extraction
try:
    from ocr_extraction import (
        ocr_document_for_mcp,
        get_ocr_status,
        extract_text_with_ocr
    )
    OCR_AVAILABLE = True
except ImportError:
    OCR_AVAILABLE = False

# Import brief synthesis (cross-case rule synthesis, circuit splits, etc.)
try:
    from brief_synthesis import (
        synthesize_brief_rules,
        analyze_circuit_split,
        generate_application_drafts,
        build_citation_string,
        generate_parentheticals_for_cases,
        format_parentheticals,
        extract_structured_case_facts,
        format_structured_facts,
        # New pipeline and file functions
        generate_brief_section,
        generate_brief_section_from_files,
        read_case_file,
        read_project_cases,
        synthesize_rules_two_pass,
        # Single-file analysis pipeline
        analyze_case_file
    )
    BRIEF_SYNTHESIS_AVAILABLE = True
except ImportError:
    BRIEF_SYNTHESIS_AVAILABLE = False

# Import case bank tools (directory processing, searchable index, semantic search)
try:
    from case_bank import (
        build_case_bank,
        search_case_bank,
        semantic_case_search,
        expand_legal_query,
        format_semantic_search
    )
    CASE_BANK_AVAILABLE = True
except ImportError:
    CASE_BANK_AVAILABLE = False

# Import brief quality tools (record cites, negative treatment, authority scoring)
try:
    from brief_quality import (
        validate_record_cites_mcp,
        detect_negative_treatment_mcp,
        score_authority_mcp,
        rank_authorities_mcp,
        extract_record_cites
    )
    BRIEF_QUALITY_AVAILABLE = True
except ImportError:
    BRIEF_QUALITY_AVAILABLE = False

# Import legal writing templates
try:
    from legal_templates import (
        generate_template_mcp,
        list_templates,
        generate_irac_template,
        generate_multielement_template,
        generate_facts_template
    )
    TEMPLATES_AVAILABLE = True
except ImportError:
    TEMPLATES_AVAILABLE = False

# Import extraction and validation tools
try:
    from extraction_validation import (
        validate_citation_accuracy_mcp,
        extract_record_facts_mcp,
        map_facts_to_elements_mcp,
        detect_factual_contradictions_mcp,
        extract_procedural_context_mcp,
        extract_reasoning_patterns_mcp,
        extract_judge_patterns_mcp,
        extract_circuit_law_mcp,
        build_chronology_mcp,
        validate_pleading_elements_mcp,
        extract_canons_and_rules_mcp,
        cross_reference_citations_mcp,
        # Quality control tools
        verify_citations_mcp,
        check_parenthetical_accuracy_mcp,
        find_adverse_authority_mcp,
        # Adversarial thinking tools
        steelman_counterargument_mcp,
        generate_distinction_mcp,
        identify_fact_gaps_mcp,
        # LUIMA-inspired sentence classification
        classify_sentence_roles,
        detect_legal_formulations,
        format_sentence_classification
    )
    EXTRACTION_VALIDATION_AVAILABLE = True
except ImportError:
    EXTRACTION_VALIDATION_AVAILABLE = False

# Import deposition processing tools
try:
    from deposition_tools import (
        ingest_deposition_mcp,
        search_deposition_mcp,
        validate_facts_against_record_mcp,
        list_ingested_depositions,
        clear_deposition_store
    )
    DEPOSITION_TOOLS_AVAILABLE = True
except ImportError:
    DEPOSITION_TOOLS_AVAILABLE = False

# Import case structuring tool
try:
    from case_structuring import structure_case_for_context_mcp
    CASE_STRUCTURING_AVAILABLE = True
except ImportError:
    CASE_STRUCTURING_AVAILABLE = False

# Import workflow orchestration tools
try:
    from workflows import (
        workflow_synthesize_rules_mcp,
        workflow_validate_brief_mcp,
        workflow_brief_this_case_mcp
    )
    WORKFLOWS_AVAILABLE = True
except ImportError:
    WORKFLOWS_AVAILABLE = False

# ============================================================================
# MCP SERVER SETUP
# ============================================================================

app = Server("citation-extractor-text")

# ============================================================================
# TOOL DEFINITIONS
# ============================================================================

@app.list_tools()
async def list_tools() -> list[Tool]:
    """List all available text-based legal analysis tools."""

    tools = [
        Tool(
            name="extract_citations",
            description=(
                "Extract legal citations from text or file. Works with any text Claude has access to - "
                "uploaded documents, web content, or pasted text. Finds case citations with pinpoint pages. "
                "Can read directly from PDF, DOCX, or TXT files for efficiency."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "text": {
                        "type": "string",
                        "description": "Document text to analyze (optional if file_path provided)"
                    },
                    "file_path": {
                        "type": "string",
                        "description": "Path to file (PDF, DOCX, TXT) - more efficient than passing text"
                    }
                },
                "required": []
            }
        ),

        Tool(
            name="extract_statutes",
            description=(
                "Extract statute and rule references from text or file. Finds USC, CFR, "
                "Federal Rules (including RULE 401 textbook format), state statutes, and Restatements. "
                "Can read directly from PDF, DOCX, or TXT files - much faster than passing text."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "text": {
                        "type": "string",
                        "description": "Document text to analyze (optional if file_path provided)"
                    },
                    "file_path": {
                        "type": "string",
                        "description": "Path to file (PDF, DOCX, TXT) - more efficient than passing text"
                    }
                },
                "required": []
            }
        ),

        Tool(
            name="search_keywords",
            description=(
                "Search for specific keywords or phrases in text. "
                "Returns occurrence counts for each keyword."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "text": {
                        "type": "string",
                        "description": "The text to search"
                    },
                    "keywords": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "List of keywords to find"
                    },
                    "case_sensitive": {
                        "type": "boolean",
                        "description": "Whether search should be case-sensitive",
                        "default": False
                    }
                },
                "required": ["text", "keywords"]
            }
        ),

        Tool(
            name="analyze_comprehensive",
            description=(
                "Perform comprehensive legal document analysis. "
                "Extracts citations, statutes, and provides document statistics."
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "text": {
                        "type": "string",
                        "description": "The document text to analyze"
                    }
                },
                "required": ["text"]
            }
        ),
    ]

    # Add enhanced citation analysis if available
    if ENHANCED_CITATIONS_AVAILABLE:
        tools.append(
            Tool(
                name="analyze_citations_deep",
                description=(
                    "ENHANCED citation analysis with relationship mapping and authority strength. "
                    "Detects: followed/distinguished/overruled relationships, controlling vs persuasive authority, "
                    "holding vs dicta context, builds citation network showing which cases cite which. "
                    "Use this for thorough brief research instead of basic extract_citations."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Document text to analyze for citations"
                        }
                    },
                    "required": ["text"]
                }
            )
        )

    # Add enhanced rule analysis if available
    if ENHANCED_RULES_AVAILABLE:
        tools.append(
            Tool(
                name="analyze_rules_deep",
                description=(
                    "Extract rules from a SINGLE case with hierarchy, classification, and pinpoint citations. "
                    "Identifies: rule types (holding, elements, test, factors, standard), "
                    "rule hierarchy (primary, sub-rule, exception), mandatory vs permissive language. "
                    "IMPORTANT: Always provide case_name and citation - without them, the extracted rules "
                    "cannot be cited in a brief. Output includes full citation with pinpoint page for each rule."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Case opinion text to analyze for rules"
                        },
                        "case_name": {
                            "type": "string",
                            "description": "REQUIRED for useful output. Case name for citation (e.g., 'Tellabs, Inc. v. Makor Issues & Rights, Ltd.')"
                        },
                        "citation": {
                            "type": "string",
                            "description": "REQUIRED for useful output. Full citation (e.g., '551 U.S. 308 (2007)'). Rules without citations cannot be used in briefs."
                        }
                    },
                    "required": ["text", "case_name", "citation"]
                }
            )
        )

    # Add law school features if available
    if LAW_FEATURES_AVAILABLE:
        tools.extend([
            Tool(
                name="bluebook_check",
                description=(
                    "Check citations against Bluebook formatting rules. "
                    "Identifies errors and suggests corrections."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Text containing citations to check"
                        }
                    },
                    "required": ["text"]
                }
            ),

            Tool(
                name="generate_table_of_authorities",
                description=(
                    "Generate a properly formatted Table of Authorities from text. "
                    "Groups by cases, statutes, etc. with page citations."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Brief or document text"
                        }
                    },
                    "required": ["text"]
                }
            ),

            Tool(
                name="filter_by_jurisdiction",
                description=(
                    "Group citations by jurisdiction and court level. "
                    "Helps identify controlling vs. persuasive authority."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Text containing citations"
                        }
                    },
                    "required": ["text"]
                }
            ),

            Tool(
                name="detect_standards_of_review",
                description=(
                    "Identify standards of review (de novo, clear error, abuse of discretion, etc.) "
                    "in judicial opinions or briefs."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Opinion or brief text"
                        }
                    },
                    "required": ["text"]
                }
            ),

            Tool(
                name="identify_legal_topics",
                description=(
                    "Identify and rank legal topics covered in text. "
                    "Useful for organizing research and outlines."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Legal document text"
                        }
                    },
                    "required": ["text"]
                }
            ),
        ])

    if CASE_ANALYSIS_AVAILABLE:
        tools.append(
            Tool(
                name="generate_case_brief",
                description=(
                    "Generate a structured case brief from an opinion. "
                    "Extracts facts, issues, holdings, reasoning, and rules."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Case opinion text"
                        }
                    },
                    "required": ["text"]
                }
            )
        )

    if STUDY_AIDS_AVAILABLE:
        tools.append(
            Tool(
                name="generate_flash_cards",
                description=(
                    "Generate flash cards from a case brief for studying. "
                    "Exports in Anki or Quizlet format."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Case brief or opinion text"
                        },
                        "format": {
                            "type": "string",
                            "enum": ["anki", "quizlet"],
                            "description": "Export format",
                            "default": "anki"
                        }
                    },
                    "required": ["text"]
                }
            )
        )

    # Advanced Analysis Tools (TIER 1 FEATURES)
    if ADVANCED_ANALYSIS_AVAILABLE:
        tools.extend([
            Tool(
                name="extract_rules",
                description=(
                    "Extract black letter rules from case text. Identifies holdings, tests, "
                    "elements, factors, and standards. Perfect for building the RULE section of IRAC."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Case opinion text"
                        },
                        "case_name": {
                            "type": "string",
                            "description": "Name of the case (optional)",
                            "default": "Unknown"
                        }
                    },
                    "required": ["text"]
                }
            ),

            Tool(
                name="extract_arguments",
                description=(
                    "Extract discrete legal arguments from a brief or opinion. "
                    "Identifies main arguments, alternatives, counter-arguments, and supporting authority."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Brief or opinion text"
                        }
                    },
                    "required": ["text"]
                }
            ),

            Tool(
                name="extract_facts",
                description=(
                    "Extract fact pattern from case or brief. Identifies procedural posture, "
                    "key facts, legally significant facts, and parties."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Case opinion or brief text"
                        }
                    },
                    "required": ["text"]
                }
            ),

            Tool(
                name="compare_cases",
                description=(
                    "Compare two cases side-by-side. Identifies similarities, differences, "
                    "distinguishing factors, and generates suggested distinction language for briefs."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "case_a_text": {
                            "type": "string",
                            "description": "Text of first case (or your client's facts)"
                        },
                        "case_b_text": {
                            "type": "string",
                            "description": "Text of second case"
                        },
                        "case_a_name": {
                            "type": "string",
                            "description": "Name of first case",
                            "default": "Your Case"
                        },
                        "case_b_name": {
                            "type": "string",
                            "description": "Name of second case",
                            "default": "Cited Case"
                        }
                    },
                    "required": ["case_a_text", "case_b_text"]
                }
            ),

            Tool(
                name="generate_memo_draft",
                description=(
                    "Generate a legal memo draft with IRAC structure. Synthesizes rules from "
                    "provided cases and creates Question Presented, Brief Answer, Facts template, "
                    "Discussion (IRAC), and Conclusion."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "issue": {
                            "type": "string",
                            "description": "The legal issue/question to analyze"
                        },
                        "facts": {
                            "type": "string",
                            "description": "Your client's facts"
                        },
                        "case_texts": {
                            "type": "object",
                            "description": "Dictionary mapping case name -> case text",
                            "additionalProperties": {"type": "string"}
                        }
                    },
                    "required": ["issue", "facts", "case_texts"]
                }
            ),

            Tool(
                name="analyze_opposing_brief",
                description=(
                    "Analyze opposing counsel's brief to extract their arguments, identify weak citations, "
                    "and generate counter-argument frameworks. Essential for response briefs."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "brief_text": {
                            "type": "string",
                            "description": "Text of opposing counsel's brief"
                        },
                        "your_facts": {
                            "type": "string",
                            "description": "Your client's facts (optional, for targeted counter-arguments)",
                            "default": ""
                        }
                    },
                    "required": ["brief_text"]
                }
            )
        ])

    # Add document export tool if available
    if DOCUMENT_FORMATTER_AVAILABLE:
        tools.append(
            Tool(
                name="export_to_word",
                description=(
                    "Export legal document content to a properly formatted Word document (.docx). "
                    "Uses 12pt Times New Roman, single-spaced, no heading styles, all black text, "
                    "with single blank line between paragraphs. Standard legal brief formatting."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "content": {
                            "type": "string",
                            "description": "The document content to export (memo, brief section, etc.)"
                        },
                        "title": {
                            "type": "string",
                            "description": "Document title (optional)",
                            "default": "LEGAL MEMORANDUM"
                        },
                        "filename": {
                            "type": "string",
                            "description": "Output filename (without path, saved to Desktop)",
                            "default": "legal_document.docx"
                        }
                    },
                    "required": ["content"]
                }
            )
        )

    # Add writing style analyzer if available
    if WRITING_STYLE_AVAILABLE:
        tools.extend([
            Tool(
                name="analyze_writing_style",
                description=(
                    "Analyze legal writing for Plain English and Chicago Manual of Style compliance. "
                    "Identifies: passive voice, nominalizations, wordy phrases, throat-clearing, "
                    "long sentences, archaic legalese, and redundant pairs. Returns specific suggestions."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Legal text to analyze for style issues"
                        }
                    },
                    "required": ["text"]
                }
            ),
            Tool(
                name="improve_writing",
                description=(
                    "Automatically improve legal writing by applying Plain English fixes. "
                    "Replaces wordy phrases, removes legalese, and provides a report of changes made."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Legal text to improve"
                        }
                    },
                    "required": ["text"]
                }
            )
        ])

    # Add IRAC synthesis tools if available
    if IRAC_SYNTHESIS_AVAILABLE:
        tools.extend([
            Tool(
                name="synthesize_irac",
                description=(
                    "KILLER FEATURE: Generate complete IRAC draft from multiple cases. "
                    "Synthesizes rules across cases (not just extracts), ranks authorities, "
                    "generates APPLICATION language with analogy/distinction drafts. "
                    "Input multiple cases + your facts, get a draft brief section."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "cases": {
                            "type": "object",
                            "description": "Dictionary mapping case_name -> {text: string, citation: string}",
                            "additionalProperties": {
                                "type": "object",
                                "properties": {
                                    "text": {"type": "string"},
                                    "citation": {"type": "string"}
                                }
                            }
                        },
                        "client_facts": {
                            "type": "string",
                            "description": "Your client's facts"
                        },
                        "issue": {
                            "type": "string",
                            "description": "The legal issue (e.g., 'whether plaintiff adequately pled scienter')"
                        },
                        "jurisdiction": {
                            "type": "string",
                            "description": "Target jurisdiction (e.g., '5th Circuit')",
                            "default": "5th Circuit"
                        }
                    },
                    "required": ["cases", "client_facts", "issue"]
                }
            ),
            Tool(
                name="rank_authorities",
                description=(
                    "Rank multiple cases by authority and relevance to your facts. "
                    "Considers: court hierarchy, jurisdiction match, recency, fact similarity. "
                    "Returns ranked list with scores and recommendations for which cases to focus on."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "cases": {
                            "type": "object",
                            "description": "Dictionary mapping case_name -> {text: string, citation: string}",
                            "additionalProperties": {
                                "type": "object",
                                "properties": {
                                    "text": {"type": "string"},
                                    "citation": {"type": "string"}
                                }
                            }
                        },
                        "your_facts": {
                            "type": "string",
                            "description": "Your client's facts for similarity comparison"
                        },
                        "jurisdiction": {
                            "type": "string",
                            "description": "Target jurisdiction",
                            "default": "5th Circuit"
                        }
                    },
                    "required": ["cases", "your_facts"]
                }
            )
        ])

    # Add argument weakness detector if available
    if ARGUMENT_WEAKNESS_AVAILABLE:
        tools.append(
            Tool(
                name="analyze_argument_weaknesses",
                description=(
                    "Analyze legal arguments for weaknesses, vulnerabilities, and areas needing improvement. "
                    "Enhanced detection: unpublished citations, dicta cited as holding, unaddressed distinctions, "
                    "conclusory transitions, missing counter-arguments, logical fallacies, weak citations, "
                    "factual gaps, overreach, unsupported assumptions, excessive hedging, conclusory statements. "
                    "Provides stage-adjusted scoring (issues matter more at summary judgment than pleading). "
                    "Returns strength score (0-100), prioritized issues, and missing counter-arguments to address."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Legal argument text to analyze for weaknesses"
                        },
                        "stage": {
                            "type": "string",
                            "description": "Litigation stage for severity adjustment",
                            "enum": ["pleading", "mtd", "discovery", "msj", "trial", "appeal"]
                        }
                    },
                    "required": ["text"]
                }
            )
        )

    # Add batch processing if available
    if BATCH_PROCESSING_AVAILABLE:
        tools.append(
            Tool(
                name="batch_analyze_documents",
                description=(
                    "Analyze multiple legal documents simultaneously. Cross-references citations across all documents, "
                    "builds master citation table, identifies shared authorities, and shows document overlap. "
                    "Input: dictionary of doc_name -> document_text. Returns comprehensive analysis with: "
                    "citation frequency, shared authorities (cases cited in multiple docs), document comparison matrix."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "documents": {
                            "type": "object",
                            "description": "Dictionary mapping document names to their text content. Example: {'Brief A': 'text...', 'Brief B': 'text...'}",
                            "additionalProperties": {"type": "string"}
                        }
                    },
                    "required": ["documents"]
                }
            )
        )

    # Add OCR extraction tool
    if OCR_AVAILABLE:
        tools.append(
            Tool(
                name="ocr_document",
                description=(
                    "Extract text from scanned PDFs or images using OCR. USE THIS FIRST if you have a scanned document "
                    "that needs text extraction before analysis. Automatically detects if PDF has embedded text (skips OCR) "
                    "or needs OCR. Supports: PDF files (scanned or regular), images (PNG, JPG, TIFF, etc.). "
                    "After extraction, use the text with other Baymax tools like extract_citations or analyze_rules_deep."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "file_path": {
                            "type": "string",
                            "description": "Full path to the PDF or image file to extract text from"
                        },
                        "force_ocr": {
                            "type": "boolean",
                            "description": "If true, always use OCR even for PDFs with embedded text. Default: false",
                            "default": False
                        }
                    },
                    "required": ["file_path"]
                }
            )
        )

        tools.append(
            Tool(
                name="ocr_status",
                description=(
                    "Check if OCR dependencies (Tesseract, Poppler) are installed and working. "
                    "Use this to diagnose OCR issues. Returns installation status and paths."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {},
                    "required": []
                }
            )
        )

    # Brief Synthesis Tools (cross-case analysis)
    if BRIEF_SYNTHESIS_AVAILABLE:
        tools.append(
            Tool(
                name="synthesize_rules_across_cases",
                description=(
                    "CROSS-CASE RULE SYNTHESIS. Analyzes MULTIPLE cases to build a unified rule hierarchy. "
                    "Use when you have 2+ cases on the same legal issue. "
                    "Builds: Primary rules -> Sub-rules -> Exceptions -> Factors. "
                    "Each rule shows which case(s) established it with full citation + pinpoint. "
                    "Output: Ready-to-paste RULE section with proper citation strings."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "cases": {
                            "type": "object",
                            "description": "Dictionary mapping case names to [text, citation] arrays. EXAMPLE: {'Tellabs v. Makor': ['The full case opinion text here...', '551 U.S. 308 (2007)'], 'Matrixx v. Siracusano': ['Another case opinion text...', '563 U.S. 27 (2011)']}"
                        },
                        "issue": {
                            "type": "string",
                            "description": "The legal issue (e.g., 'scienter under PSLRA'). Helps focus extraction."
                        },
                        "jurisdiction": {
                            "type": "string",
                            "description": "Your circuit (e.g., '5th Circuit'). Used to tag binding vs. persuasive authority."
                        }
                    },
                    "required": ["cases"]
                }
            )
        )

        tools.append(
            Tool(
                name="detect_circuit_split",
                description=(
                    "Detect circuit splits on a legal issue. Analyzes cases from different circuits to identify "
                    "conflicting rules. Returns: each circuit's position, Supreme Court status (resolved/unresolved), "
                    "majority position, and your jurisdiction's binding rule. Essential for federal practice."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "cases": {
                            "type": "object",
                            "description": "Dictionary mapping case names to [text, citation] arrays"
                        },
                        "issue": {
                            "type": "string",
                            "description": "The specific legal issue to analyze for splits"
                        },
                        "your_jurisdiction": {
                            "type": "string",
                            "description": "Your circuit (e.g., '5th Circuit', 'D.C. Circuit')"
                        }
                    },
                    "required": ["cases", "issue", "your_jurisdiction"]
                }
            )
        )

        tools.append(
            Tool(
                name="generate_application_section",
                description=(
                    "Generate draft APPLICATION section content with enhanced features: "
                    "(1) Analogy/distinction language weighted by fact significance (determinative vs. supporting), "
                    "(2) Record citations embedded in draft language, "
                    "(3) 'Even if' alternative arguments for fallback positions, "
                    "(4) Element-specific fact mapping. Automates APPLICATION section drafting."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "precedent_cases": {
                            "type": "object",
                            "description": "Dictionary mapping case names to [text, citation] arrays"
                        },
                        "client_facts": {
                            "type": "string",
                            "description": "Your client's factual situation"
                        },
                        "issue": {
                            "type": "string",
                            "description": "The legal issue being briefed"
                        },
                        "elements": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "Optional: Legal elements to map facts to (e.g., ['duty', 'breach', 'causation', 'damages'])"
                        },
                        "record_cites": {
                            "type": "object",
                            "description": "Optional: Dict mapping fact keywords to record citations (e.g., {'testified': 'Smith Dep. 45:10'})"
                        }
                    },
                    "required": ["precedent_cases", "client_facts", "issue"]
                }
            )
        )

        tools.append(
            Tool(
                name="build_citation_string",
                description=(
                    "Build a Bluebook-compliant citation string from multiple cases supporting the same proposition. "
                    "Handles signals (See, See also, Cf., But see), semicolon separation, and 'accord' for 3+ cases. "
                    "Output ready to paste into your brief."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "cases": {
                            "type": "array",
                            "description": "Array of [case_name, citation, pinpoint_page] arrays",
                            "items": {
                                "type": "array",
                                "items": {"type": "string"}
                            }
                        },
                        "signal": {
                            "type": "string",
                            "description": "Citation signal: 'See', 'See, e.g.,', 'Cf.', 'But see', 'See also'. Default: 'See'",
                            "default": "See"
                        },
                        "proposition": {
                            "type": "string",
                            "description": "Optional: The proposition these cases support (prepended to citation string)"
                        }
                    },
                    "required": ["cases"]
                }
            )
        )

        tools.append(
            Tool(
                name="generate_parentheticals",
                description=(
                    "GENERATE CITATION PARENTHETICALS. For each case, extracts the key holding and formats "
                    "as a Bluebook-compliant parenthetical: (holding that...) or (finding that...). "
                    "Returns FULL CITATION STRING ready to paste: 'Case Name, 123 F.3d 456, 460 (5th Cir. 2020) (holding that...)'. "
                    "Use after rule synthesis to get paste-ready citations for your brief."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "cases": {
                            "type": "object",
                            "description": "Dictionary: case names to [text, citation] arrays. EXAMPLE: {'Tellabs': ['text...', '551 U.S. 308 (2007)']}"
                        },
                        "rule_focus": {
                            "type": "string",
                            "description": "Optional: Specific rule text to focus parentheticals on"
                        }
                    },
                    "required": ["cases"]
                }
            )
        )

        tools.append(
            Tool(
                name="extract_case_facts_structured",
                description=(
                    "Extract STRUCTURED facts from a case for analogy/distinction analysis. "
                    "Returns: (1) Operative facts - what happened, (2) Procedural posture, "
                    "(3) Outcome, (4) DETERMINATIVE facts - what court found decisive (use for analogies), "
                    "(5) INSUFFICIENT facts - what court found inadequate (use for distinctions), "
                    "(6) Disputed vs. undisputed facts. Essential for APPLICATION section drafting."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "case_text": {
                            "type": "string",
                            "description": "Full text of the case opinion"
                        },
                        "case_name": {
                            "type": "string",
                            "description": "Name of the case for output formatting"
                        }
                    },
                    "required": ["case_text"]
                }
            )
        )

        # Pipeline function - single-call brief generation
        tools.append(
            Tool(
                name="generate_brief_section",
                description=(
                    "ALL-IN-ONE BRIEF GENERATOR. Use this when you have cases + client facts and want a complete draft. "
                    "Runs the full pipeline: extract rules -> synthesize hierarchy -> generate parentheticals -> "
                    "draft APPLICATION section with analogies/distinctions. "
                    "OUTPUT: Complete RULE + APPLICATION sections with all citations ready to paste into brief."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "precedent_cases": {
                            "type": "object",
                            "description": "Dictionary mapping case names to [text, citation] arrays. EXAMPLE: {'Tellabs': ['full text...', '551 U.S. 308 (2007)']}"
                        },
                        "issue": {
                            "type": "string",
                            "description": "The legal issue (e.g., 'scienter under PSLRA')"
                        },
                        "client_facts": {
                            "type": "string",
                            "description": "Your client's factual situation for the APPLICATION section"
                        },
                        "jurisdiction": {
                            "type": "string",
                            "description": "Target circuit (e.g., '5th Circuit')"
                        },
                        "elements": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "Optional: Legal elements to organize analysis"
                        },
                        "record_cites": {
                            "type": "object",
                            "description": "Optional: Dict mapping fact keywords to record citations (e.g., {'testified': 'Smith Dep. 45:10'})"
                        }
                    },
                    "required": ["precedent_cases", "issue", "client_facts", "jurisdiction"]
                }
            )
        )

        # File reading function
        tools.append(
            Tool(
                name="read_case_file",
                description=(
                    "Read case text directly from a file (PDF, TXT, DOCX, MD). "
                    "Extracts text content and attempts to identify the citation. "
                    "Use this to load cases from your project files instead of copy-pasting."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "file_path": {
                            "type": "string",
                            "description": "Path to the case file (absolute or relative)"
                        }
                    },
                    "required": ["file_path"]
                }
            )
        )

        # Generate brief from files
        tools.append(
            Tool(
                name="generate_brief_from_files",
                description=(
                    "Generate complete RULE + APPLICATION sections by reading case files directly. "
                    "Combines file reading with the full brief generation pipeline. "
                    "Point it at your case PDFs/documents and get ready-to-paste output."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "case_files": {
                            "type": "object",
                            "description": "Dictionary mapping case names to file paths"
                        },
                        "issue": {
                            "type": "string",
                            "description": "The legal issue being briefed"
                        },
                        "client_facts": {
                            "type": "string",
                            "description": "Your client's factual situation"
                        },
                        "jurisdiction": {
                            "type": "string",
                            "description": "Target jurisdiction (e.g., '5th Circuit')"
                        },
                        "base_path": {
                            "type": "string",
                            "description": "Optional: Base directory for relative file paths"
                        },
                        "elements": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "Optional: Legal elements to organize analysis"
                        },
                        "record_cites": {
                            "type": "object",
                            "description": "Optional: Dict mapping fact keywords to record citations"
                        }
                    },
                    "required": ["case_files", "issue", "client_facts", "jurisdiction"]
                }
            )
        )

        # Two-pass synthesis for long cases
        tools.append(
            Tool(
                name="synthesize_rules_two_pass",
                description=(
                    "Two-pass rule synthesis for LONG cases that fragment with regular extraction. "
                    "Pass 1: Identifies rule-containing sections (holdings, conclusions). "
                    "Pass 2: Extracts complete rules from those sections only. "
                    "Prevents fragmentation and captures full holdings."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "cases": {
                            "type": "object",
                            "description": "Dictionary mapping case names to [text, citation] arrays"
                        },
                        "issue": {
                            "type": "string",
                            "description": "The legal issue for context"
                        },
                        "jurisdiction": {
                            "type": "string",
                            "description": "Optional: Your jurisdiction for binding/persuasive tagging"
                        }
                    },
                    "required": ["cases", "issue"]
                }
            )
        )

    # Brief Quality Tools (record cites, negative treatment, authority scoring)
    if BRIEF_QUALITY_AVAILABLE:
        tools.append(
            Tool(
                name="validate_record_cites",
                description=(
                    "CRITICAL FOR FILING. Scans your brief for factual assertions and validates they have record support. "
                    "Extracts all record cites (R. 123, Doc. 45-2, Exh. A, Tr. 50:1, etc.). "
                    "Flags factual claims WITHOUT record support with [NEED CITE: ___]. "
                    "Returns coverage percentage and prioritized list of unsupported assertions."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "brief_text": {
                            "type": "string",
                            "description": "Your draft brief text to validate"
                        }
                    },
                    "required": ["brief_text"]
                }
            )
        )

        tools.append(
            Tool(
                name="detect_negative_treatment",
                description=(
                    "Partial Shepardizing without Westlaw. Scans case text for negative treatment signals: "
                    "overruled, distinguished, limited, questioned, criticized. "
                    "Returns severity rating and context quotes. "
                    "NOT a substitute for full Shepard's but catches obvious problems."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "case_name": {
                            "type": "string",
                            "description": "Name of the case to check (e.g., 'Tellabs v. Makor')"
                        },
                        "case_citation": {
                            "type": "string",
                            "description": "Citation of the case to check"
                        },
                        "source_text": {
                            "type": "string",
                            "description": "Text to scan for negative treatment (e.g., a later case opinion)"
                        }
                    },
                    "required": ["case_name", "case_citation", "source_text"]
                }
            )
        )

        tools.append(
            Tool(
                name="score_authority",
                description=(
                    "Score a case's strength as authority (0-100). Considers: court level, jurisdiction match, "
                    "recency, and treatment history. Returns recommendation: 'Lead citation', 'Strong support', etc. "
                    "Use to determine citation order in your brief."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "case_name": {
                            "type": "string",
                            "description": "Name of the case"
                        },
                        "citation": {
                            "type": "string",
                            "description": "Full citation"
                        },
                        "your_jurisdiction": {
                            "type": "string",
                            "description": "Your circuit/court (e.g., '5th Circuit')"
                        },
                        "issue": {
                            "type": "string",
                            "description": "The legal issue"
                        }
                    },
                    "required": ["case_name", "citation", "your_jurisdiction", "issue"]
                }
            )
        )

        tools.append(
            Tool(
                name="rank_authorities",
                description=(
                    "Rank multiple cases by authority strength for optimal citation order. "
                    "Returns sorted list with scores and recommendation for lead citation, "
                    "strong support, and string cite ordering."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "cases": {
                            "type": "object",
                            "description": "Dictionary mapping case names to citations. Example: {'Tellabs': '551 U.S. 308 (2007)'}"
                        },
                        "your_jurisdiction": {
                            "type": "string",
                            "description": "Your circuit/court"
                        },
                        "issue": {
                            "type": "string",
                            "description": "The legal issue being briefed"
                        }
                    },
                    "required": ["cases", "your_jurisdiction", "issue"]
                }
            )
        )

    # Legal Writing Templates
    if TEMPLATES_AVAILABLE:
        tools.append(
            Tool(
                name="generate_template",
                description=(
                    "Generate legal writing templates with placeholders to fill in. "
                    "NOT AI prose - structured scaffolds that force you to add substance. "
                    "Types: irac, creac, multielement, facts, synthesis, standard, conclusion, roadmap. "
                    "Returns template with [PLACEHOLDERS] for you to complete."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "template_type": {
                            "type": "string",
                            "description": "Template type: 'irac', 'creac', 'multielement', 'facts', 'synthesis', 'standard', 'conclusion', 'roadmap'",
                            "enum": ["irac", "creac", "multielement", "facts", "synthesis", "standard", "conclusion", "roadmap"]
                        },
                        "thesis": {
                            "type": "string",
                            "description": "Your thesis/conclusion (for irac, creac)"
                        },
                        "rule_name": {
                            "type": "string",
                            "description": "Name of the rule being applied (for irac, creac)"
                        },
                        "facts": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "List of key facts to address"
                        },
                        "elements": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "List of elements (for multielement template)"
                        },
                        "claim": {
                            "type": "string",
                            "description": "The claim/cause of action (for multielement)"
                        },
                        "relief": {
                            "type": "string",
                            "description": "Relief requested (for conclusion)"
                        },
                        "reasons": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "Key reasons (for conclusion)"
                        }
                    },
                    "required": ["template_type"]
                }
            )
        )

        tools.append(
            Tool(
                name="list_templates",
                description="List all available legal writing templates with descriptions.",
                inputSchema={
                    "type": "object",
                    "properties": {},
                    "required": []
                }
            )
        )

    # Extraction and Validation Tools
    if EXTRACTION_VALIDATION_AVAILABLE:
        tools.append(
            Tool(
                name="validate_citation_accuracy",
                description=(
                    "Validate that citations in a brief actually support the propositions claimed. "
                    "Flags citations where case may not say what you claim. "
                    "Returns JSON with each citation, claimed proposition, confidence score, and flags."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "brief_text": {
                            "type": "string",
                            "description": "The brief text containing citations to validate"
                        }
                    },
                    "required": ["brief_text"]
                }
            )
        )

        tools.append(
            Tool(
                name="extract_record_facts",
                description=(
                    "Extract legally significant facts from record documents (depositions, exhibits, discovery). "
                    "Returns JSON with facts, record citations, dates, witnesses, and significance classifications."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "record_text": {
                            "type": "string",
                            "description": "Text from record document (deposition, exhibit, etc.)"
                        },
                        "document_name": {
                            "type": "string",
                            "description": "Name/identifier for the source document (e.g., 'Smith Deposition', 'Exhibit A')"
                        }
                    },
                    "required": ["record_text"]
                }
            )
        )

        tools.append(
            Tool(
                name="map_facts_to_elements",
                description=(
                    "Map extracted facts to legal claim elements. Shows which facts satisfy which elements, "
                    "identifies gaps in proof, and scores sufficiency. Returns JSON for element-by-element analysis."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "claim": {
                            "type": "string",
                            "description": "The legal claim (e.g., '42 U.S.C. 1983 excessive force')"
                        },
                        "elements": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "List of required elements for the claim"
                        },
                        "facts": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "fact": {"type": "string"},
                                    "record_cite": {"type": "string"}
                                }
                            },
                            "description": "List of facts with record citations"
                        }
                    },
                    "required": ["claim", "elements", "facts"]
                }
            )
        )

        tools.append(
            Tool(
                name="detect_factual_contradictions",
                description=(
                    "Detect contradictions between multiple documents (your brief, record, opposing brief). "
                    "Finds direct conflicts, inconsistencies, and omissions. "
                    "Returns JSON with contradictions and their sources."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "documents": {
                            "type": "object",
                            "additionalProperties": {"type": "string"},
                            "description": "Dict mapping document names to their text content"
                        }
                    },
                    "required": ["documents"]
                }
            )
        )

        tools.append(
            Tool(
                name="extract_procedural_context",
                description=(
                    "Extract procedural posture, standard of review, burden of proof, and jurisdictional basis. "
                    "Returns JSON with procedural context for tailoring arguments."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Case opinion or brief text to analyze"
                        }
                    },
                    "required": ["text"]
                }
            )
        )

        tools.append(
            Tool(
                name="extract_reasoning_patterns",
                description=(
                    "Extract argument/reasoning types used in a case (analogical, policy, textual, purposive, etc.). "
                    "Returns JSON with reasoning patterns, strength scores, and text snippets."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "case_text": {
                            "type": "string",
                            "description": "Full text of case opinion to analyze"
                        }
                    },
                    "required": ["case_text"]
                }
            )
        )

        tools.append(
            Tool(
                name="extract_judge_patterns",
                description=(
                    "Analyze a judge's prior opinions to find reasoning tendencies, favored authorities, "
                    "and procedural preferences. Returns JSON for tailoring arguments to specific judge."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "opinions": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "text": {"type": "string"},
                                    "case_name": {"type": "string"}
                                }
                            },
                            "description": "List of judge's opinions with text and case names"
                        },
                        "judge_name": {
                            "type": "string",
                            "description": "Name of the judge"
                        }
                    },
                    "required": ["opinions", "judge_name"]
                }
            )
        )

        tools.append(
            Tool(
                name="extract_circuit_law",
                description=(
                    "Extract circuit-specific rules, binding precedent, and circuit splits. "
                    "Returns JSON with controlling law for your jurisdiction."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "cases": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "text": {"type": "string"},
                                    "case_name": {"type": "string"}
                                }
                            },
                            "description": "List of circuit cases with text and names"
                        },
                        "circuit": {
                            "type": "string",
                            "description": "Circuit identifier (e.g., '9th Circuit', '5th Cir.')"
                        }
                    },
                    "required": ["cases", "circuit"]
                }
            )
        )

        tools.append(
            Tool(
                name="build_chronology",
                description=(
                    "Build a timeline from record documents. Extracts all dates and events, "
                    "identifies gaps. Returns JSON timeline for Statement of Facts."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "documents": {
                            "type": "object",
                            "additionalProperties": {"type": "string"},
                            "description": "Dict mapping document names to their text content"
                        }
                    },
                    "required": ["documents"]
                }
            )
        )

        tools.append(
            Tool(
                name="validate_pleading_elements",
                description=(
                    "Validate that a pleading contains required elements for a claim. "
                    "Identifies missing elements and suggests fixes. "
                    "Supports: 1983_excessive_force, 1983_false_arrest, negligence, breach_of_contract, "
                    "fraud, defamation, title_vii_discrimination, ada_discrimination."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "pleading_text": {
                            "type": "string",
                            "description": "Text of complaint or answer"
                        },
                        "claim_type": {
                            "type": "string",
                            "description": "Type of claim (e.g., '1983_excessive_force', 'negligence')"
                        }
                    },
                    "required": ["pleading_text", "claim_type"]
                }
            )
        )

        tools.append(
            Tool(
                name="extract_canons",
                description=(
                    "Extract interpretive canons used in statutory interpretation (plain meaning, "
                    "legislative history, rule of lenity, constitutional avoidance, etc.). "
                    "Returns JSON with canons detected and interpretation approach."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Case text discussing statutory interpretation"
                        }
                    },
                    "required": ["text"]
                }
            )
        )

        tools.append(
            Tool(
                name="cross_reference_citations",
                description=(
                    "Cross-reference citations across multiple documents. "
                    "Finds shared authorities, unique citations, and overlap patterns. "
                    "Returns JSON with citation analysis matrix."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "documents": {
                            "type": "object",
                            "additionalProperties": {"type": "string"},
                            "description": "Dict mapping document names to their text content"
                        }
                    },
                    "required": ["documents"]
                }
            )
        )

        # Quality Control Tools
        tools.append(
            Tool(
                name="verify_citations",
                description=(
                    "Verify that quoted language in your brief matches the source cases. "
                    "Searches for exact and close matches, flags discrepancies. "
                    "Returns: VERIFIED (exact match), CLOSE_MATCH (shows differences), "
                    "NOT_FOUND (quote not in source), CASE_MISSING (case not provided)."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "brief_text": {
                            "type": "string",
                            "description": "Your brief containing citations with quoted language"
                        },
                        "case_texts": {
                            "type": "object",
                            "additionalProperties": {"type": "string"},
                            "description": "Dict mapping case names to their full text"
                        }
                    },
                    "required": ["brief_text", "case_texts"]
                }
            )
        )

        tools.append(
            Tool(
                name="check_parenthetical_accuracy",
                description=(
                    "Verify that parentheticals accurately represent case holdings. "
                    "Flags: ACCURATE (holding matches), OVERSTATED (claim broader than holding), "
                    "UNDERSTATED (missing important qualifications), UNSUPPORTED (cannot find support). "
                    "Suggests revisions for inaccurate parentheticals."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "parentheticals": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "case_name": {"type": "string"},
                                    "parenthetical_text": {"type": "string"}
                                }
                            },
                            "description": "List of {case_name, parenthetical_text} objects"
                        },
                        "case_texts": {
                            "type": "object",
                            "additionalProperties": {"type": "string"},
                            "description": "Dict mapping case names to their full text"
                        }
                    },
                    "required": ["parentheticals", "case_texts"]
                }
            )
        )

        tools.append(
            Tool(
                name="find_adverse_authority",
                description=(
                    "Analyze cases to find holdings that undermine your argument. "
                    "Identifies adverse holdings, explains the conflict, and suggests "
                    "distinguishing language. Essential for anticipating opposing arguments. "
                    "Rates severity: FATAL, SERIOUS, MINOR."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "your_argument": {
                            "type": "string",
                            "description": "Your legal argument text"
                        },
                        "case_texts": {
                            "type": "object",
                            "additionalProperties": {"type": "string"},
                            "description": "Dict mapping case names to their full text"
                        }
                    },
                    "required": ["your_argument", "case_texts"]
                }
            )
        )

        # Adversarial Thinking Tools
        tools.append(
            Tool(
                name="steelman_counterargument",
                description=(
                    "Generate the strongest possible opposing response to your argument. "
                    "Identifies attack vectors, adverse holdings, element weaknesses, and "
                    "produces a paste-ready opposing paragraph. Use before filing to "
                    "stress-test your arguments."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "your_argument": {
                            "type": "string",
                            "description": "Your legal argument text to attack"
                        },
                        "case_texts": {
                            "type": "object",
                            "additionalProperties": {"type": "string"},
                            "description": "Dict mapping case names to their full text"
                        },
                        "claim_type": {
                            "type": "string",
                            "description": "Optional claim type (e.g., 'negligence', 'breach of contract')"
                        }
                    },
                    "required": ["your_argument", "case_texts"]
                }
            )
        )

        tools.append(
            Tool(
                name="generate_distinction",
                description=(
                    "Generate paste-ready distinction language for an adverse case. "
                    "Analyzes the adverse holding and facts, compares to your facts, "
                    "and produces multiple options for distinguishing the case. "
                    "Returns factual, procedural, legal issue, or scope distinctions."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "adverse_case_name": {
                            "type": "string",
                            "description": "Name of the adverse case"
                        },
                        "adverse_case_text": {
                            "type": "string",
                            "description": "Full text of the adverse case"
                        },
                        "adverse_citation": {
                            "type": "string",
                            "description": "Citation for the adverse case"
                        },
                        "your_facts": {
                            "type": "string",
                            "description": "Description of your case facts"
                        },
                        "your_position": {
                            "type": "string",
                            "description": "Your legal position/argument"
                        }
                    },
                    "required": ["adverse_case_name", "adverse_case_text", "adverse_citation", "your_facts", "your_position"]
                }
            )
        )

        tools.append(
            Tool(
                name="identify_fact_gaps",
                description=(
                    "Identify missing facts needed to satisfy each element of a legal standard. "
                    "Maps your facts to elements, calculates sufficiency scores, and suggests "
                    "discovery targets for weak elements. Essential for motion practice."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "legal_standard": {
                            "type": "string",
                            "description": "The legal standard or test being applied"
                        },
                        "elements": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "List of required elements"
                        },
                        "your_facts": {
                            "type": "string",
                            "description": "Description of facts you have"
                        },
                        "record_available": {
                            "type": "string",
                            "description": "Optional description of available record sources"
                        }
                    },
                    "required": ["legal_standard", "elements", "your_facts"]
                }
            )
        )

    # Deposition Processing Tools
    if DEPOSITION_TOOLS_AVAILABLE:
        tools.append(
            Tool(
                name="ingest_deposition",
                description=(
                    "Parse a deposition transcript and extract Q/A pairs with page:line citations. "
                    "Builds a searchable index with topic tagging. "
                    "Stores transcript in memory for subsequent search and validation queries."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "transcript_text": {
                            "type": "string",
                            "description": "Full text of the deposition transcript"
                        },
                        "witness_name": {
                            "type": "string",
                            "description": "Name of the deponent"
                        },
                        "deposition_date": {
                            "type": "string",
                            "description": "Date of deposition (optional)"
                        },
                        "case_name": {
                            "type": "string",
                            "description": "Case name for citation formatting (optional)"
                        }
                    },
                    "required": ["transcript_text", "witness_name"]
                }
            )
        )

        tools.append(
            Tool(
                name="search_deposition",
                description=(
                    "Search ingested depositions for relevant testimony. "
                    "Query by keyword, witness name, citation range, or topic. "
                    "Returns matching Q/A pairs with citations and relevance scores."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "query": {
                            "type": "string",
                            "description": "Search text"
                        },
                        "witness": {
                            "type": "string",
                            "description": "Filter by witness name (optional)"
                        },
                        "cite_range_start": {
                            "type": "string",
                            "description": "Start of citation range, e.g., '45:1' (optional)"
                        },
                        "cite_range_end": {
                            "type": "string",
                            "description": "End of citation range, e.g., '50:25' (optional)"
                        },
                        "topics": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "Filter by topics: timeline, knowledge, actions, documents, communications, injuries, employment, training"
                        },
                        "include_context": {
                            "type": "boolean",
                            "description": "Include surrounding Q/A pairs for context (default: true)",
                            "default": True
                        }
                    },
                    "required": ["query"]
                }
            )
        )

        tools.append(
            Tool(
                name="validate_facts_against_record",
                description=(
                    "Validate Statement of Facts against ingested deposition database. "
                    "Classifies each assertion as SUPPORTED, UNSUPPORTED, or CONTRADICTED. "
                    "Returns coverage percentage and suggested citations for unsupported facts."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "statement_of_facts": {
                            "type": "string",
                            "description": "Text of Statement of Facts section"
                        },
                        "record_sources": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "List of witness names to check against (optional, checks all if not specified)"
                        }
                    },
                    "required": ["statement_of_facts"]
                }
            )
        )

    # Case Structuring Tool
    if CASE_STRUCTURING_AVAILABLE:
        tools.append(
            Tool(
                name="structure_case_for_context",
                description=(
                    "PRE-PROCESS A CASE FOR EASIER NAVIGATION. Converts raw case text into structured markdown "
                    "with labeled sections: ## HOLDING, ## RULE FRAMEWORK, ## KEY FACTS, ## REASONING, etc. "
                    "Use this BEFORE detailed analysis when dealing with a long or complex case. "
                    "Makes subsequent rule extraction and analysis more accurate. "
                    "Accepts file_path OR raw case_text."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "case_text": {
                            "type": "string",
                            "description": "Full text of case opinion (use this OR file_path)"
                        },
                        "file_path": {
                            "type": "string",
                            "description": "Path to case file (PDF, DOCX, TXT) - alternative to case_text"
                        },
                        "case_name": {
                            "type": "string",
                            "description": "Case name (auto-detected if not provided)"
                        },
                        "citation": {
                            "type": "string",
                            "description": "Full citation (auto-detected if not provided)"
                        },
                        "include_full_text": {
                            "type": "boolean",
                            "description": "Append complete original text at end (default: true)",
                            "default": True
                        }
                    },
                    "required": []
                }
            )
        )

    # Workflow Automation Tools
    if BRIEF_SYNTHESIS_AVAILABLE:
        tools.append(
            Tool(
                name="analyze_case_file",
                description=(
                    "EASIEST ENTRY POINT. Reads a case file and extracts everything: rules, holdings, elements, "
                    "parentheticals. Auto-detects case name and citation from the text. "
                    "Use this FIRST when given a case file - it handles reading + full analysis in one call. "
                    "Returns rules with citations ready to use in other tools or directly in briefs."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "file_path": {
                            "type": "string",
                            "description": "Path to case file (PDF, DOCX, TXT). Tool auto-detects case name and citation."
                        }
                    },
                    "required": ["file_path"]
                }
            )
        )

    if CASE_BANK_AVAILABLE:
        tools.append(
            Tool(
                name="build_case_bank",
                description=(
                    "Process all case files in a directory into a searchable case bank. "
                    "Extracts rules and holdings from each file, builds cross-references, "
                    "and saves a JSON index for later querying. "
                    "Returns rules organized by type with case attribution."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "directory_path": {
                            "type": "string",
                            "description": "Path to directory containing case files"
                        },
                        "file_pattern": {
                            "type": "string",
                            "description": "File pattern to match (e.g., '*.pdf', '*.txt'). Default: '*.pdf'",
                            "default": "*.pdf"
                        }
                    },
                    "required": ["directory_path"]
                }
            )
        )
        tools.append(
            Tool(
                name="search_case_bank",
                description=(
                    "Search a previously-built case bank index for rules and holdings. "
                    "Can filter by keyword query, rule type (holding, elements, test, factors, etc.), "
                    "or case name. Returns matching rules with their case attribution and citations."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "index_path": {
                            "type": "string",
                            "description": "Path to case_bank_index.json file created by build_case_bank"
                        },
                        "query": {
                            "type": "string",
                            "description": "Text to search for in rule content (optional)"
                        },
                        "rule_type": {
                            "type": "string",
                            "description": "Filter by rule type: holding, test, elements, factors, standard, bright_line, balancing, multi_factor, totality, presumption, definition (optional)"
                        },
                        "case_name": {
                            "type": "string",
                            "description": "Filter by case name (optional)"
                        }
                    },
                    "required": ["index_path"]
                }
            )
        )
        tools.append(
            Tool(
                name="semantic_case_search",
                description=(
                    "SMART SEARCH: Search case bank using natural language with automatic query expansion. "
                    "Expands legal terms to related concepts (e.g., 'scienter' → 'fraudulent intent', 'intent to deceive'). "
                    "Can filter by sentence role (holdings, rules, findings). Much more powerful than basic search. "
                    "Example: 'Find holdings about scienter pled through reckless conduct'"
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "index_path": {
                            "type": "string",
                            "description": "Path to case_bank_index.json"
                        },
                        "query": {
                            "type": "string",
                            "description": "Natural language query - will be expanded to related legal concepts"
                        },
                        "max_results": {
                            "type": "integer",
                            "description": "Maximum results to return (default: 20)",
                            "default": 20
                        },
                        "min_relevance": {
                            "type": "number",
                            "description": "Minimum relevance score 0-1 (default: 0.3)",
                            "default": 0.3
                        }
                    },
                    "required": ["index_path", "query"]
                }
            )
        )
        tools.append(
            Tool(
                name="expand_legal_query",
                description=(
                    "Expand a natural language legal query into structured search terms. "
                    "Shows how query will be interpreted: detected legal concepts, term expansions, "
                    "target sentence role. Useful to understand or refine searches."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "query": {
                            "type": "string",
                            "description": "Natural language query to expand"
                        }
                    },
                    "required": ["query"]
                }
            )
        )

    # LUIMA-inspired sentence classification tools
    if EXTRACTION_VALIDATION_AVAILABLE:
        tools.append(
            Tool(
                name="classify_sentence_roles",
                description=(
                    "SMART ANALYSIS: Classify every sentence in legal text by its argumentative function. "
                    "Identifies: LegalRule, LegalHolding, EvidenceBasedFinding, EvidenceSummary, "
                    "Citation, ProceduralFact, PolicyReasoning, PartyArgument, Dicta. "
                    "Also detects high-confidence legal formulations (burden statements, element tests, etc.). "
                    "Use this to understand what a case actually HOLDS vs what it merely DISCUSSES."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Full case text to analyze"
                        },
                        "file_path": {
                            "type": "string",
                            "description": "Path to case file (PDF, DOCX, TXT) - alternative to text"
                        },
                        "include_unknown": {
                            "type": "boolean",
                            "description": "Include sentences with unknown roles (default: True)",
                            "default": True
                        }
                    },
                    "required": []
                }
            )
        )
        tools.append(
            Tool(
                name="detect_legal_formulations",
                description=(
                    "Extract high-confidence legal rule formulations from text. "
                    "Finds: standard formulations ('plaintiff must prove X'), burden statements, "
                    "legal tests, exceptions, element lists. These are the most reliable rule extractions. "
                    "Returns formulation type, extracted components, and confidence score."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "text": {
                            "type": "string",
                            "description": "Text to search for legal formulations"
                        },
                        "file_path": {
                            "type": "string",
                            "description": "Path to file (PDF, DOCX, TXT) - alternative to text"
                        }
                    },
                    "required": []
                }
            )
        )

    # =========================================================================
    # WORKFLOW TOOLS - Single-call pipelines for common tasks
    # =========================================================================

    if WORKFLOWS_AVAILABLE:
        tools.append(
            Tool(
                name="workflow_synthesize_rules",
                description=(
                    "ONE-CALL RULE SYNTHESIS. Provide case files OR case texts and get a complete, "
                    "paste-ready RULE section with citations. Chains: read files -> extract rules -> "
                    "synthesize hierarchy -> generate parentheticals. Returns partial results if any "
                    "step fails. USE THIS instead of manually calling multiple tools."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "file_paths": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "List of paths to case files (PDF, DOCX, TXT). Tool auto-extracts case names and citations."
                        },
                        "case_texts": {
                            "type": "object",
                            "description": "Alternative to files. Dict: case_name -> [text, citation]. Example: {'Tellabs': ['full text...', '551 U.S. 308']}"
                        },
                        "issue": {
                            "type": "string",
                            "description": "The legal issue (e.g., 'scienter under PSLRA'). Helps focus extraction."
                        },
                        "jurisdiction": {
                            "type": "string",
                            "description": "Your circuit (e.g., '5th Circuit'). Tags rules as binding/persuasive."
                        }
                    },
                    "required": []
                }
            )
        )

        tools.append(
            Tool(
                name="workflow_validate_brief",
                description=(
                    "ONE-CALL BRIEF QC. Runs ALL validation checks before filing: "
                    "(1) verify quoted language matches sources, "
                    "(2) check parentheticals don't overstate holdings, "
                    "(3) find factual claims without record citations, "
                    "(4) detect adverse authority. Returns comprehensive report with issues flagged."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "brief_text": {
                            "type": "string",
                            "description": "Your draft brief text to validate"
                        },
                        "case_texts": {
                            "type": "object",
                            "additionalProperties": {"type": "string"},
                            "description": "Dict: case_name -> case_text. Needed for citation/parenthetical verification."
                        },
                        "check_citations": {
                            "type": "boolean",
                            "description": "Run citation verification (default: true)",
                            "default": True
                        },
                        "check_parentheticals": {
                            "type": "boolean",
                            "description": "Run parenthetical accuracy check (default: true)",
                            "default": True
                        },
                        "check_record_cites": {
                            "type": "boolean",
                            "description": "Run record citation validation (default: true)",
                            "default": True
                        },
                        "find_adverse": {
                            "type": "boolean",
                            "description": "Run adverse authority detection (default: true)",
                            "default": True
                        }
                    },
                    "required": ["brief_text"]
                }
            )
        )

        tools.append(
            Tool(
                name="brief_this_case",
                description=(
                    "ONE-CALL CASE BRIEFING. Give me a case and get EVERYTHING: "
                    "structured facts (operative, determinative, disputed, undisputed), "
                    "procedural posture, rules/holdings with pinpoint cites, "
                    "outcome, and paste-ready parenthetical. "
                    "Perfect for quickly briefing a new case before using it."
                ),
                inputSchema={
                    "type": "object",
                    "properties": {
                        "file_path": {
                            "type": "string",
                            "description": "Path to case file (PDF, DOCX, TXT). Alternative to case_text."
                        },
                        "case_text": {
                            "type": "string",
                            "description": "Raw case text. Alternative to file_path."
                        },
                        "case_name": {
                            "type": "string",
                            "description": "Case name (e.g., 'Smith v. Jones'). Extracted from filename if not provided."
                        },
                        "citation": {
                            "type": "string",
                            "description": "Full citation (e.g., '123 F.3d 456 (5th Cir. 2020)'). Extracted from text if not provided."
                        }
                    },
                    "required": []
                }
            )
        )

    return tools


# ============================================================================
# TOOL HANDLERS
# ============================================================================

@app.call_tool()
async def call_tool(name: str, arguments: Any) -> Sequence[TextContent]:
    """Handle tool calls from MCP clients (Claude Desktop)."""

    # Core extraction tools
    if name == "extract_citations":
        text = arguments.get("text")
        file_path = arguments.get("file_path")

        # Read from file if path provided
        if file_path and BRIEF_SYNTHESIS_AVAILABLE:
            try:
                text, file_type = read_case_file(file_path)
                # Check if read_case_file returned an error
                if file_type == "error" or (text and text.startswith("Error")):
                    return [TextContent(type="text", text=f"File reading error: {text}")]
                if not text:
                    return [TextContent(type="text", text=f"Error: Could not read file: {file_path}")]
            except Exception as e:
                return [TextContent(type="text", text=f"Error reading file: {str(e)}")]
        elif file_path and not BRIEF_SYNTHESIS_AVAILABLE:
            return [TextContent(type="text", text="Error: File reading not available")]
        elif not text:
            return [TextContent(type="text", text="Error: Either text or file_path must be provided")]

        citations = extract_citations_from_text(text)
        output = format_citations_output(citations)

        if file_path:
            output = f"File: {file_path}\n\n" + output

        return [TextContent(type="text", text=output)]

    elif name == "extract_statutes":
        text = arguments.get("text")
        file_path = arguments.get("file_path")

        # Read from file if path provided
        if file_path and BRIEF_SYNTHESIS_AVAILABLE:
            try:
                text, file_type = read_case_file(file_path)
                # Check if read_case_file returned an error
                if file_type == "error" or (text and text.startswith("Error")):
                    return [TextContent(type="text", text=f"File reading error: {text}")]
                if not text:
                    return [TextContent(type="text", text=f"Error: Could not read file: {file_path}")]
            except Exception as e:
                return [TextContent(type="text", text=f"Error reading file: {str(e)}")]
        elif file_path and not BRIEF_SYNTHESIS_AVAILABLE:
            return [TextContent(type="text", text="Error: File reading not available - brief_synthesis module not found")]
        elif not text:
            return [TextContent(type="text", text="Error: Either text or file_path must be provided")]

        statutes = extract_statutes_from_text(text)
        output = format_statutes_output(statutes)

        # Add file info to output if read from file
        if file_path:
            output = f"File: {file_path}\n\n" + output

        return [TextContent(type="text", text=output)]

    elif name == "search_keywords":
        text = arguments["text"]
        keywords = arguments["keywords"]
        case_sensitive = arguments.get("case_sensitive", False)

        results = search_keywords_in_text(text, keywords, case_sensitive)
        output = format_keywords_output(results)
        return [TextContent(type="text", text=output)]

    elif name == "analyze_comprehensive":
        text = arguments["text"]
        analysis = analyze_text_comprehensive(text)

        output = []
        output.append("COMPREHENSIVE LEGAL ANALYSIS")
        output.append("=" * 70)
        output.append(f"\nDocument Statistics:")
        output.append(f"  - Word count: {analysis['word_count']:,}")
        output.append(f"  - Character count: {analysis['text_length']:,}")
        output.append(f"\nLegal References:")
        output.append(f"  - Unique citations: {analysis['total_citations']}")
        output.append(f"  - Unique statutes: {analysis['total_statutes']}")
        output.append("\n" + "=" * 70)
        output.append("\nCITATIONS:")
        output.append(format_citations_output(analysis['citations']))
        output.append("\n" + "=" * 70)
        output.append("\nSTATUTES:")
        output.append(format_statutes_output(analysis['statutes']))

        return [TextContent(type="text", text='\n'.join(output))]

    # Enhanced citation analysis
    elif name == "analyze_citations_deep" and ENHANCED_CITATIONS_AVAILABLE:
        text = arguments["text"]
        output = analyze_citations_enhanced(text)
        return [TextContent(type="text", text=output)]

    # Enhanced rule analysis
    elif name == "analyze_rules_deep" and ENHANCED_RULES_AVAILABLE:
        text = arguments["text"]
        case_name = arguments.get("case_name", "Unknown")
        citation = arguments.get("citation")
        output = analyze_rules_enhanced(text, case_name, citation)
        return [TextContent(type="text", text=output)]

    # Law school features
    elif name == "bluebook_check" and LAW_FEATURES_AVAILABLE:
        text = arguments["text"]
        citations = extract_citations_from_text(text)

        output = []
        output.append("BLUEBOOK FORMAT CHECK")
        output.append("=" * 70)
        output.append(f"\nTotal citations checked: {len(citations)}\n")

        errors_found = 0
        for citation in sorted(citations.keys()):
            result = format_case_citation_bluebook(citation)

            if result.errors:
                errors_found += 1
                output.append(f"\n• {citation}")
                output.append(f"  Errors:")
                for error in result.errors:
                    output.append(f"    - {error}")
                if result.suggestions:
                    output.append(f"  Suggestions:")
                    for suggestion in result.suggestions:
                        output.append(f"    - {suggestion}")
            else:
                output.append(f"\n• {citation}")
                output.append(f"  ✓ Properly formatted")

        output.insert(3, f"Errors found: {errors_found}\n")
        return [TextContent(type="text", text='\n'.join(output))]

    elif name == "generate_table_of_authorities" and LAW_FEATURES_AVAILABLE:
        text = arguments["text"]
        citations = extract_citations_from_text(text)
        statutes = extract_statutes_from_text(text)

        toa = generate_table_of_authorities(citations, statutes)
        return [TextContent(type="text", text=toa)]

    elif name == "filter_by_jurisdiction" and LAW_FEATURES_AVAILABLE:
        text = arguments["text"]
        citations = extract_citations_from_text(text)

        from legal_analysis import group_by_jurisdiction
        grouped = group_by_jurisdiction(citations)

        output = []
        output.append("CITATIONS BY JURISDICTION")
        output.append("=" * 70 + "\n")

        for jurisdiction, cites in grouped.items():
            output.append(f"\n{jurisdiction.value}")
            output.append("-" * 70)
            for cite in sorted(cites):
                output.append(f"  • {cite}")

        return [TextContent(type="text", text='\n'.join(output))]

    elif name == "detect_standards_of_review" and LAW_FEATURES_AVAILABLE:
        text = arguments["text"]
        standards = detect_standards_of_review(text)

        output = []
        output.append("STANDARDS OF REVIEW DETECTED")
        output.append("=" * 70)
        output.append(f"\nTotal found: {len(standards)}\n")

        for standard, context, position in standards:
            output.append(f"\n• {standard.value}")
            output.append(f"  Context: {context}")

        return [TextContent(type="text", text='\n'.join(output))]

    elif name == "identify_legal_topics" and LAW_FEATURES_AVAILABLE:
        text = arguments["text"]
        topics = identify_primary_topics(text, top_n=10)

        output = []
        output.append("LEGAL TOPICS IDENTIFIED")
        output.append("=" * 70 + "\n")

        for topic, score in topics:
            output.append(f"• {topic}: {score}")

        return [TextContent(type="text", text='\n'.join(output))]

    elif name == "generate_case_brief" and CASE_ANALYSIS_AVAILABLE:
        text = arguments["text"]
        brief = extract_case_brief(text)

        output = []
        output.append(f"CASE BRIEF: {brief.get('case_name', 'Unknown Case')}")
        output.append("=" * 70)

        if brief.get('citation'):
            output.append(f"\nCitation: {brief['citation']}")
        if brief.get('court'):
            output.append(f"Court: {brief['court']}")
        if brief.get('year'):
            output.append(f"Year: {brief['year']}")

        if brief.get('facts'):
            output.append("\n\nFACTS:")
            for fact in brief['facts']:
                output.append(f"  • {fact}")

        if brief.get('issues'):
            output.append("\n\nISSUES:")
            for issue in brief['issues']:
                output.append(f"  • {issue}")

        if brief.get('holdings'):
            output.append("\n\nHOLDINGS:")
            for holding in brief['holdings']:
                output.append(f"  • {holding}")

        if brief.get('reasoning'):
            output.append("\n\nREASONING:")
            for reason in brief['reasoning']:
                output.append(f"  • {reason}")

        if brief.get('rule'):
            output.append("\n\nRULES:")
            for rule in brief['rule']:
                output.append(f"  • {rule}")

        return [TextContent(type="text", text='\n'.join(output))]

    elif name == "generate_flash_cards" and STUDY_AIDS_AVAILABLE:
        text = arguments["text"]
        format_type = arguments.get("format", "anki")

        # First extract brief
        brief = extract_case_brief(text)

        # Generate cards
        cards = generate_flash_cards_from_brief(brief)

        # Format for export
        if format_type == "anki":
            formatted = format_flash_cards_anki(cards)
        else:
            formatted = format_flash_cards_quizlet(cards)

        output = []
        output.append(f"FLASH CARDS ({format_type.upper()} FORMAT)")
        output.append("=" * 70)
        output.append(f"\nTotal cards generated: {len(cards)}\n")
        output.append(formatted)

        return [TextContent(type="text", text='\n'.join(output))]

    # ========================================================================
    # ADVANCED ANALYSIS TOOLS (TIER 1 - BRIEF WRITING WEAPONS)
    # ========================================================================

    elif name == "extract_rules" and ADVANCED_ANALYSIS_AVAILABLE:
        text = arguments["text"]
        case_name = arguments.get("case_name", "Unknown")
        output = analyze_for_rules(text, case_name)
        return [TextContent(type="text", text=output)]

    elif name == "extract_arguments" and ADVANCED_ANALYSIS_AVAILABLE:
        text = arguments["text"]
        # Also extract citations for context
        citations = extract_citations_from_text(text)
        output = analyze_for_arguments(text, citations)
        return [TextContent(type="text", text=output)]

    elif name == "extract_facts" and ADVANCED_ANALYSIS_AVAILABLE:
        text = arguments["text"]
        output = analyze_for_facts(text)
        return [TextContent(type="text", text=output)]

    elif name == "compare_cases" and ADVANCED_ANALYSIS_AVAILABLE:
        case_a_text = arguments["case_a_text"]
        case_b_text = arguments["case_b_text"]
        case_a_name = arguments.get("case_a_name", "Your Case")
        case_b_name = arguments.get("case_b_name", "Cited Case")
        output = compare_two_cases(case_a_text, case_b_text, case_a_name, case_b_name)
        return [TextContent(type="text", text=output)]

    elif name == "generate_memo_draft" and ADVANCED_ANALYSIS_AVAILABLE:
        issue = arguments["issue"]
        facts = arguments["facts"]
        case_texts = arguments.get("case_texts", {})
        output = generate_memo(issue, facts, case_texts)
        return [TextContent(type="text", text=output)]

    elif name == "analyze_opposing_brief" and ADVANCED_ANALYSIS_AVAILABLE:
        brief_text = arguments["brief_text"]
        your_facts = arguments.get("your_facts", "")
        output = analyze_opposing(brief_text, your_facts)
        return [TextContent(type="text", text=output)]

    # Document export tool
    elif name == "export_to_word" and DOCUMENT_FORMATTER_AVAILABLE:
        content = arguments["content"]
        title = arguments.get("title", "LEGAL MEMORANDUM")
        filename = arguments.get("filename", "legal_document.docx")

        # Ensure filename ends with .docx
        if not filename.endswith('.docx'):
            filename += '.docx'

        # Save to Desktop (handles OneDrive redirection)
        output_path = str(get_desktop_path() / filename)

        # Parse content into sections
        sections = parse_memo_sections(content)

        if DOCX_AVAILABLE:
            result = create_legal_document(sections, output_path, title)
            return [TextContent(type="text", text=result)]
        else:
            # Return formatted plain text if docx not available
            formatted = get_formatted_output(sections, title)
            return [TextContent(type="text", text=f"python-docx not available. Here is formatted text:\n\n{formatted}")]

    # Writing style tools
    elif name == "analyze_writing_style" and WRITING_STYLE_AVAILABLE:
        text = arguments["text"]
        output = analyze_writing_style(text)
        return [TextContent(type="text", text=output)]

    elif name == "improve_writing" and WRITING_STYLE_AVAILABLE:
        text = arguments["text"]
        output = improve_legal_writing(text)
        return [TextContent(type="text", text=output)]

    # IRAC synthesis tools
    elif name == "synthesize_irac" and IRAC_SYNTHESIS_AVAILABLE:
        cases_raw = arguments["cases"]
        client_facts = arguments["client_facts"]
        issue = arguments["issue"]
        jurisdiction = arguments.get("jurisdiction", "5th Circuit")

        # Convert case format: {name: {text, citation}} -> {name: (text, citation)}
        cases = {}
        for case_name, case_data in cases_raw.items():
            if isinstance(case_data, dict):
                cases[case_name] = (case_data.get("text", ""), case_data.get("citation", ""))
            else:
                cases[case_name] = (str(case_data), "")

        output = generate_irac_draft(cases, client_facts, issue, jurisdiction)
        return [TextContent(type="text", text=output)]

    elif name == "rank_authorities" and IRAC_SYNTHESIS_AVAILABLE:
        cases_raw = arguments["cases"]
        your_facts = arguments["your_facts"]
        jurisdiction = arguments.get("jurisdiction", "5th Circuit")

        # Convert case format
        cases = {}
        for case_name, case_data in cases_raw.items():
            if isinstance(case_data, dict):
                cases[case_name] = (case_data.get("text", ""), case_data.get("citation", ""))
            else:
                cases[case_name] = (str(case_data), "")

        output = rank_authorities(cases, your_facts, jurisdiction)
        return [TextContent(type="text", text=output)]

    # Argument weakness detector
    elif name == "analyze_argument_weaknesses" and ARGUMENT_WEAKNESS_AVAILABLE:
        text = arguments["text"]
        stage_str = arguments.get("stage")
        stage = None
        if stage_str:
            stage_map = {
                "pleading": LitigationStage.PLEADING,
                "mtd": LitigationStage.MOTION_TO_DISMISS,
                "discovery": LitigationStage.DISCOVERY,
                "msj": LitigationStage.SUMMARY_JUDGMENT,
                "trial": LitigationStage.TRIAL,
                "appeal": LitigationStage.APPEAL
            }
            stage = stage_map.get(stage_str)
        report = analyze_argument_weaknesses(text, stage=stage)
        output = format_weakness_report(report)
        return [TextContent(type="text", text=output)]

    # Batch processing
    elif name == "batch_analyze_documents" and BATCH_PROCESSING_AVAILABLE:
        documents = arguments["documents"]
        output = batch_analyze_formatted(documents)
        return [TextContent(type="text", text=output)]

    # OCR extraction tools
    elif name == "ocr_document" and OCR_AVAILABLE:
        file_path = arguments["file_path"]
        force_ocr = arguments.get("force_ocr", False)
        output = ocr_document_for_mcp(file_path, force_ocr)
        return [TextContent(type="text", text=output)]

    elif name == "ocr_status" and OCR_AVAILABLE:
        status = get_ocr_status()
        output = ["OCR SYSTEM STATUS", "=" * 50]
        output.append(f"Tesseract OCR: {'INSTALLED' if status['tesseract_available'] else 'NOT FOUND'}")
        if status['tesseract_path']:
            output.append(f"  Path: {status['tesseract_path']}")
        output.append(f"PDF2Image: {'AVAILABLE' if status['pdf2image_available'] else 'NOT AVAILABLE'}")
        if status['poppler_path']:
            output.append(f"  Poppler Path: {status['poppler_path']}")
        output.append(f"PyPDF: {'AVAILABLE' if status['pypdf_available'] else 'NOT AVAILABLE'}")
        output.append(f"\nFully Operational: {'YES' if status['fully_operational'] else 'NO'}")

        if not status['fully_operational']:
            output.append("\nMISSING DEPENDENCIES:")
            if not status['tesseract_available']:
                output.append("  - Tesseract OCR: https://github.com/UB-Mannheim/tesseract/wiki")
            if not status['pdf2image_available']:
                output.append("  - pdf2image: pip install pdf2image")
            if not status['poppler_path'] and status['pdf2image_available']:
                output.append("  - Poppler: https://github.com/oschwartz10612/poppler-windows/releases")

        return [TextContent(type="text", text="\n".join(output))]

    # Brief Synthesis tools
    elif name == "synthesize_rules_across_cases" and BRIEF_SYNTHESIS_AVAILABLE:
        cases_raw = arguments["cases"]
        issue = arguments.get("issue")
        jurisdiction = arguments.get("jurisdiction")

        # Convert cases format: {"name": ["text", "cite"]} -> {"name": ("text", "cite")}
        cases = {}
        for case_name, case_data in cases_raw.items():
            if isinstance(case_data, list) and len(case_data) >= 2:
                cases[case_name] = (case_data[0], case_data[1])
            elif isinstance(case_data, dict):
                cases[case_name] = (case_data.get("text", ""), case_data.get("citation", ""))

        output = synthesize_brief_rules(cases, issue, jurisdiction)
        return [TextContent(type="text", text=output)]

    elif name == "detect_circuit_split" and BRIEF_SYNTHESIS_AVAILABLE:
        cases_raw = arguments["cases"]
        issue = arguments["issue"]
        your_jurisdiction = arguments["your_jurisdiction"]

        # Convert cases format
        cases = {}
        for case_name, case_data in cases_raw.items():
            if isinstance(case_data, list) and len(case_data) >= 2:
                cases[case_name] = (case_data[0], case_data[1])

        output = analyze_circuit_split(cases, issue, your_jurisdiction)
        return [TextContent(type="text", text=output)]

    elif name == "generate_application_section" and BRIEF_SYNTHESIS_AVAILABLE:
        precedent_cases_raw = arguments["precedent_cases"]
        client_facts = arguments["client_facts"]
        issue = arguments["issue"]
        elements = arguments.get("elements")
        record_cites = arguments.get("record_cites")

        # Convert cases format
        precedent_cases = {}
        for case_name, case_data in precedent_cases_raw.items():
            if isinstance(case_data, list) and len(case_data) >= 2:
                precedent_cases[case_name] = (case_data[0], case_data[1])

        output = generate_application_drafts(
            precedent_cases, client_facts, issue,
            elements=elements, record_cites=record_cites
        )
        return [TextContent(type="text", text=output)]

    elif name == "build_citation_string" and BRIEF_SYNTHESIS_AVAILABLE:
        cases = arguments["cases"]  # [[name, cite, pinpoint], ...]
        signal = arguments.get("signal", "See")
        proposition = arguments.get("proposition")

        # Convert to tuples
        cases_tuples = [(c[0], c[1], c[2] if len(c) > 2 else "") for c in cases]

        output = build_citation_string(cases_tuples, signal, proposition)
        return [TextContent(type="text", text=output)]

    elif name == "generate_parentheticals" and BRIEF_SYNTHESIS_AVAILABLE:
        cases_raw = arguments["cases"]
        rule_focus = arguments.get("rule_focus")

        # Convert cases format
        cases = {}
        for case_name, case_data in cases_raw.items():
            if isinstance(case_data, list) and len(case_data) >= 2:
                cases[case_name] = (case_data[0], case_data[1])

        parentheticals = generate_parentheticals_for_cases(cases, rule_focus)
        output = format_parentheticals(parentheticals)
        return [TextContent(type="text", text=output)]

    elif name == "extract_case_facts_structured" and BRIEF_SYNTHESIS_AVAILABLE:
        case_text = arguments["case_text"]
        case_name = arguments.get("case_name", "")

        facts = extract_structured_case_facts(case_text)
        output = format_structured_facts(facts, case_name)
        return [TextContent(type="text", text=output)]

    elif name == "generate_brief_section" and BRIEF_SYNTHESIS_AVAILABLE:
        precedent_cases_raw = arguments["precedent_cases"]
        issue = arguments["issue"]
        client_facts = arguments["client_facts"]
        jurisdiction = arguments["jurisdiction"]
        elements = arguments.get("elements")
        record_cites = arguments.get("record_cites")

        # Convert cases format
        precedent_cases = {}
        for case_name, case_data in precedent_cases_raw.items():
            if isinstance(case_data, list) and len(case_data) >= 2:
                precedent_cases[case_name] = (case_data[0], case_data[1])

        output = generate_brief_section(
            precedent_cases, issue, client_facts, jurisdiction,
            elements=elements, record_cites=record_cites
        )
        return [TextContent(type="text", text=output)]

    elif name == "read_case_file" and BRIEF_SYNTHESIS_AVAILABLE:
        file_path = arguments["file_path"]

        text, file_type = read_case_file(file_path)

        output = []
        output.append(f"FILE TYPE: {file_type}")
        output.append(f"PATH: {file_path}")
        output.append("=" * 70)
        output.append("")
        output.append(text[:50000] if len(text) > 50000 else text)  # Limit output size

        if len(text) > 50000:
            output.append("")
            output.append(f"[TRUNCATED - showing first 50000 of {len(text)} characters]")

        return [TextContent(type="text", text='\n'.join(output))]

    elif name == "generate_brief_from_files" and BRIEF_SYNTHESIS_AVAILABLE:
        case_files = arguments["case_files"]
        issue = arguments["issue"]
        client_facts = arguments["client_facts"]
        jurisdiction = arguments["jurisdiction"]
        base_path = arguments.get("base_path")
        elements = arguments.get("elements")
        record_cites = arguments.get("record_cites")

        output = generate_brief_section_from_files(
            case_files, issue, client_facts, jurisdiction,
            base_path=base_path, elements=elements, record_cites=record_cites
        )
        return [TextContent(type="text", text=output)]

    elif name == "synthesize_rules_two_pass" and BRIEF_SYNTHESIS_AVAILABLE:
        cases_raw = arguments["cases"]
        issue = arguments["issue"]
        jurisdiction = arguments.get("jurisdiction")

        # Convert cases format
        cases = {}
        for case_name, case_data in cases_raw.items():
            if isinstance(case_data, list) and len(case_data) >= 2:
                cases[case_name] = (case_data[0], case_data[1])

        output = synthesize_rules_two_pass(cases, issue, jurisdiction)
        return [TextContent(type="text", text=output)]

    # Brief Quality tools
    elif name == "validate_record_cites" and BRIEF_QUALITY_AVAILABLE:
        brief_text = arguments["brief_text"]
        output = validate_record_cites_mcp(brief_text)
        return [TextContent(type="text", text=output)]

    elif name == "detect_negative_treatment" and BRIEF_QUALITY_AVAILABLE:
        case_name = arguments["case_name"]
        case_citation = arguments["case_citation"]
        source_text = arguments["source_text"]
        output = detect_negative_treatment_mcp(case_name, case_citation, source_text)
        return [TextContent(type="text", text=output)]

    elif name == "score_authority" and BRIEF_QUALITY_AVAILABLE:
        case_name = arguments["case_name"]
        citation = arguments["citation"]
        your_jurisdiction = arguments["your_jurisdiction"]
        issue = arguments["issue"]
        output = score_authority_mcp(case_name, citation, your_jurisdiction, issue)
        return [TextContent(type="text", text=output)]

    elif name == "rank_authorities" and BRIEF_QUALITY_AVAILABLE:
        cases = arguments["cases"]
        your_jurisdiction = arguments["your_jurisdiction"]
        issue = arguments["issue"]
        output = rank_authorities_mcp(cases, your_jurisdiction, issue)
        return [TextContent(type="text", text=output)]

    elif name == "generate_template" and TEMPLATES_AVAILABLE:
        template_type = arguments["template_type"]
        kwargs = {k: v for k, v in arguments.items() if k != "template_type"}
        output = generate_template_mcp(template_type, **kwargs)
        return [TextContent(type="text", text=output)]

    elif name == "list_templates" and TEMPLATES_AVAILABLE:
        output = list_templates()
        return [TextContent(type="text", text=output)]

    # Extraction and Validation Tools
    elif name == "validate_citation_accuracy" and EXTRACTION_VALIDATION_AVAILABLE:
        brief_text = arguments["brief_text"]
        output = validate_citation_accuracy_mcp(brief_text)
        return [TextContent(type="text", text=output)]

    elif name == "extract_record_facts" and EXTRACTION_VALIDATION_AVAILABLE:
        record_text = arguments["record_text"]
        document_name = arguments.get("document_name", "Record")
        output = extract_record_facts_mcp(record_text, document_name)
        return [TextContent(type="text", text=output)]

    elif name == "map_facts_to_elements" and EXTRACTION_VALIDATION_AVAILABLE:
        claim = arguments["claim"]
        elements = arguments["elements"]
        facts = arguments["facts"]
        output = map_facts_to_elements_mcp(claim, elements, facts)
        return [TextContent(type="text", text=output)]

    elif name == "detect_factual_contradictions" and EXTRACTION_VALIDATION_AVAILABLE:
        documents = arguments["documents"]
        output = detect_factual_contradictions_mcp(documents)
        return [TextContent(type="text", text=output)]

    elif name == "extract_procedural_context" and EXTRACTION_VALIDATION_AVAILABLE:
        text = arguments["text"]
        output = extract_procedural_context_mcp(text)
        return [TextContent(type="text", text=output)]

    elif name == "extract_reasoning_patterns" and EXTRACTION_VALIDATION_AVAILABLE:
        case_text = arguments["case_text"]
        output = extract_reasoning_patterns_mcp(case_text)
        return [TextContent(type="text", text=output)]

    elif name == "extract_judge_patterns" and EXTRACTION_VALIDATION_AVAILABLE:
        opinions = arguments["opinions"]
        judge_name = arguments["judge_name"]
        output = extract_judge_patterns_mcp(opinions, judge_name)
        return [TextContent(type="text", text=output)]

    elif name == "extract_circuit_law" and EXTRACTION_VALIDATION_AVAILABLE:
        cases = arguments["cases"]
        circuit = arguments["circuit"]
        output = extract_circuit_law_mcp(cases, circuit)
        return [TextContent(type="text", text=output)]

    elif name == "build_chronology" and EXTRACTION_VALIDATION_AVAILABLE:
        documents = arguments["documents"]
        output = build_chronology_mcp(documents)
        return [TextContent(type="text", text=output)]

    elif name == "validate_pleading_elements" and EXTRACTION_VALIDATION_AVAILABLE:
        pleading_text = arguments["pleading_text"]
        claim_type = arguments["claim_type"]
        output = validate_pleading_elements_mcp(pleading_text, claim_type)
        return [TextContent(type="text", text=output)]

    elif name == "extract_canons" and EXTRACTION_VALIDATION_AVAILABLE:
        text = arguments["text"]
        output = extract_canons_and_rules_mcp(text)
        return [TextContent(type="text", text=output)]

    elif name == "cross_reference_citations" and EXTRACTION_VALIDATION_AVAILABLE:
        documents = arguments["documents"]
        output = cross_reference_citations_mcp(documents)
        return [TextContent(type="text", text=output)]

    # Quality Control Tools
    elif name == "verify_citations" and EXTRACTION_VALIDATION_AVAILABLE:
        brief_text = arguments["brief_text"]
        case_texts = arguments["case_texts"]
        output = verify_citations_mcp(brief_text, case_texts)
        return [TextContent(type="text", text=output)]

    elif name == "check_parenthetical_accuracy" and EXTRACTION_VALIDATION_AVAILABLE:
        parentheticals = arguments["parentheticals"]
        case_texts = arguments["case_texts"]
        output = check_parenthetical_accuracy_mcp(parentheticals, case_texts)
        return [TextContent(type="text", text=output)]

    elif name == "find_adverse_authority" and EXTRACTION_VALIDATION_AVAILABLE:
        your_argument = arguments["your_argument"]
        case_texts = arguments["case_texts"]
        output = find_adverse_authority_mcp(your_argument, case_texts)
        return [TextContent(type="text", text=output)]

    # Adversarial Thinking Tools
    elif name == "steelman_counterargument" and EXTRACTION_VALIDATION_AVAILABLE:
        your_argument = arguments["your_argument"]
        case_texts = arguments["case_texts"]
        claim_type = arguments.get("claim_type")
        output = steelman_counterargument_mcp(your_argument, case_texts, claim_type)
        return [TextContent(type="text", text=output)]

    elif name == "generate_distinction" and EXTRACTION_VALIDATION_AVAILABLE:
        adverse_case_name = arguments["adverse_case_name"]
        adverse_case_text = arguments["adverse_case_text"]
        adverse_citation = arguments["adverse_citation"]
        your_facts = arguments["your_facts"]
        your_position = arguments["your_position"]
        output = generate_distinction_mcp(
            adverse_case_name, adverse_case_text, adverse_citation,
            your_facts, your_position
        )
        return [TextContent(type="text", text=output)]

    elif name == "identify_fact_gaps" and EXTRACTION_VALIDATION_AVAILABLE:
        legal_standard = arguments["legal_standard"]
        elements = arguments["elements"]
        your_facts = arguments["your_facts"]
        record_available = arguments.get("record_available")
        output = identify_fact_gaps_mcp(legal_standard, elements, your_facts, record_available)
        return [TextContent(type="text", text=output)]

    # Deposition Processing Tools
    elif name == "ingest_deposition" and DEPOSITION_TOOLS_AVAILABLE:
        transcript_text = arguments["transcript_text"]
        witness_name = arguments["witness_name"]
        deposition_date = arguments.get("deposition_date")
        case_name = arguments.get("case_name")
        output = ingest_deposition_mcp(transcript_text, witness_name, deposition_date, case_name)
        return [TextContent(type="text", text=output)]

    elif name == "search_deposition" and DEPOSITION_TOOLS_AVAILABLE:
        query = arguments["query"]
        witness = arguments.get("witness")
        cite_range_start = arguments.get("cite_range_start")
        cite_range_end = arguments.get("cite_range_end")
        topics = arguments.get("topics")
        include_context = arguments.get("include_context", True)
        output = search_deposition_mcp(
            query, witness, cite_range_start, cite_range_end,
            topics, include_context
        )
        return [TextContent(type="text", text=output)]

    elif name == "validate_facts_against_record" and DEPOSITION_TOOLS_AVAILABLE:
        statement_of_facts = arguments["statement_of_facts"]
        record_sources = arguments.get("record_sources")
        output = validate_facts_against_record_mcp(statement_of_facts, record_sources)
        return [TextContent(type="text", text=output)]

    # Case Structuring Tool
    elif name == "structure_case_for_context" and CASE_STRUCTURING_AVAILABLE:
        case_text = arguments.get("case_text")
        file_path = arguments.get("file_path")
        case_name = arguments.get("case_name")
        citation = arguments.get("citation")
        include_full_text = arguments.get("include_full_text", True)
        output = structure_case_for_context_mcp(
            case_text=case_text,
            case_name=case_name,
            citation=citation,
            include_full_text=include_full_text,
            file_path=file_path
        )
        return [TextContent(type="text", text=output)]

    # Workflow Automation Tools
    elif name == "analyze_case_file" and BRIEF_SYNTHESIS_AVAILABLE:
        file_path = arguments["file_path"]
        output = analyze_case_file(file_path)
        return [TextContent(type="text", text=output)]

    elif name == "build_case_bank" and CASE_BANK_AVAILABLE:
        directory_path = arguments["directory_path"]
        file_pattern = arguments.get("file_pattern", "*.pdf")
        output = build_case_bank(directory_path, file_pattern)
        return [TextContent(type="text", text=output)]

    elif name == "search_case_bank" and CASE_BANK_AVAILABLE:
        index_path = arguments["index_path"]
        query = arguments.get("query")
        rule_type = arguments.get("rule_type")
        case_name = arguments.get("case_name")

        results = search_case_bank(index_path, query, rule_type, case_name)

        # Format output
        output = []
        output.append("=" * 70)
        output.append("CASE BANK SEARCH RESULTS")
        output.append("=" * 70)
        output.append(f"\nIndex: {index_path}")
        if query:
            output.append(f"Query: {query}")
        if rule_type:
            output.append(f"Rule type: {rule_type}")
        if case_name:
            output.append(f"Case name: {case_name}")
        output.append(f"\nFound: {len(results)} matching rules\n")

        for i, rule in enumerate(results[:50], 1):  # Limit to 50 results
            output.append(f"--- Result {i} ---")
            output.append(f"Case: {rule.get('case_name', 'Unknown')}")
            if rule.get('citation'):
                output.append(f"Citation: {rule['citation']}")
            output.append(f"Type: {rule.get('rule_type', 'unknown').upper()}")
            if rule.get('pinpoint'):
                output.append(f"Pinpoint: {rule['pinpoint']}")
            output.append(f"Rule: {rule.get('text', '[No text]')}")
            if rule.get('elements'):
                output.append(f"Elements: {rule['elements']}")
            if rule.get('factors'):
                output.append(f"Factors: {rule['factors']}")
            output.append("")

        if len(results) > 50:
            output.append(f"... and {len(results) - 50} more results")

        return [TextContent(type="text", text="\n".join(output))]

    elif name == "semantic_case_search" and CASE_BANK_AVAILABLE:
        index_path = arguments["index_path"]
        query = arguments["query"]
        max_results = arguments.get("max_results", 20)
        min_relevance = arguments.get("min_relevance", 0.3)

        result = semantic_case_search(index_path, query, max_results, min_relevance)
        output = format_semantic_search(result)
        return [TextContent(type="text", text=output)]

    elif name == "expand_legal_query" and CASE_BANK_AVAILABLE:
        query = arguments["query"]
        result = expand_legal_query(query)

        output = []
        output.append("=" * 70)
        output.append("QUERY EXPANSION")
        output.append("=" * 70)
        output.append(f"\nOriginal: {result['original_query']}")
        output.append(f"Target role: {result.get('target_role', 'any')}")
        output.append(f"Relationship: {result.get('relationship_type', 'none')}")
        output.append(f"Strategy: {result.get('search_strategy', 'keyword')}")

        if result.get('matched_terms'):
            output.append(f"\nMatched legal terms: {', '.join(result['matched_terms'])}")
        if result.get('expanded_terms'):
            output.append(f"\nExpanded to: {', '.join(result['expanded_terms'][:15])}")
        if result.get('exact_phrases'):
            output.append(f"\nExact phrases: {result['exact_phrases']}")

        return [TextContent(type="text", text="\n".join(output))]

    elif name == "classify_sentence_roles" and EXTRACTION_VALIDATION_AVAILABLE:
        text = arguments.get("text")
        file_path = arguments.get("file_path")
        include_unknown = arguments.get("include_unknown", True)

        # Read from file if path provided
        if file_path and BRIEF_SYNTHESIS_AVAILABLE:
            try:
                text, file_type = read_case_file(file_path)
                # Check if read_case_file returned an error
                if file_type == "error" or text.startswith("Error"):
                    return [TextContent(type="text", text=f"File reading error: {text}")]
            except Exception as e:
                return [TextContent(type="text", text=f"Error reading file: {str(e)}")]
        elif file_path and not BRIEF_SYNTHESIS_AVAILABLE:
            return [TextContent(type="text", text="Error: File reading not available")]
        elif not text:
            return [TextContent(type="text", text="Error: Either text or file_path required")]

        result = classify_sentence_roles(text, include_unknown)
        output = format_sentence_classification(result)
        return [TextContent(type="text", text=output)]

    elif name == "detect_legal_formulations" and EXTRACTION_VALIDATION_AVAILABLE:
        text = arguments.get("text")
        file_path = arguments.get("file_path")

        # Read from file if path provided
        if file_path and BRIEF_SYNTHESIS_AVAILABLE:
            try:
                text, file_type = read_case_file(file_path)
                # Check if read_case_file returned an error
                if file_type == "error" or text.startswith("Error"):
                    return [TextContent(type="text", text=f"File reading error: {text}")]
            except Exception as e:
                return [TextContent(type="text", text=f"Error reading file: {str(e)}")]
        elif file_path and not BRIEF_SYNTHESIS_AVAILABLE:
            return [TextContent(type="text", text="Error: File reading not available")]
        elif not text:
            return [TextContent(type="text", text="Error: Either text or file_path required")]

        formulations = detect_legal_formulations(text)

        output = []
        output.append("=" * 70)
        output.append("LEGAL FORMULATIONS DETECTED")
        output.append("=" * 70)
        output.append(f"\nFound {len(formulations)} legal formulations\n")

        for i, f in enumerate(formulations[:25], 1):
            output.append(f"--- Formulation {i} [{f.formulation_type.upper()}] ---")
            output.append(f"Confidence: {f.confidence:.0%}")
            output.append(f"Text: {f.text[:300]}{'...' if len(f.text) > 300 else ''}")
            if f.extracted_components:
                output.append(f"Components: {f.extracted_components}")
            output.append("")

        return [TextContent(type="text", text="\n".join(output))]

    # =========================================================================
    # WORKFLOW TOOLS
    # =========================================================================

    elif name == "workflow_synthesize_rules" and WORKFLOWS_AVAILABLE:
        file_paths = arguments.get("file_paths")
        case_texts = arguments.get("case_texts")
        issue = arguments.get("issue")
        jurisdiction = arguments.get("jurisdiction")

        if not file_paths and not case_texts:
            return [TextContent(type="text", text="Error: Must provide file_paths or case_texts")]

        output = workflow_synthesize_rules_mcp(
            file_paths=file_paths,
            case_texts=case_texts,
            issue=issue,
            jurisdiction=jurisdiction
        )
        return [TextContent(type="text", text=output)]

    elif name == "workflow_validate_brief" and WORKFLOWS_AVAILABLE:
        brief_text = arguments.get("brief_text")
        case_texts = arguments.get("case_texts")
        check_citations = arguments.get("check_citations", True)
        check_parentheticals = arguments.get("check_parentheticals", True)
        check_record_cites = arguments.get("check_record_cites", True)
        find_adverse = arguments.get("find_adverse", True)

        if not brief_text:
            return [TextContent(type="text", text="Error: brief_text is required")]

        output = workflow_validate_brief_mcp(
            brief_text=brief_text,
            case_texts=case_texts,
            check_citations=check_citations,
            check_parentheticals=check_parentheticals,
            check_record_cites=check_record_cites,
            find_adverse=find_adverse
        )
        return [TextContent(type="text", text=output)]

    elif name == "brief_this_case" and WORKFLOWS_AVAILABLE:
        file_path = arguments.get("file_path")
        case_text = arguments.get("case_text")
        case_name = arguments.get("case_name")
        citation = arguments.get("citation")

        if not file_path and not case_text:
            return [TextContent(type="text", text="Error: Provide either file_path or case_text")]

        output = workflow_brief_this_case_mcp(
            file_path=file_path,
            case_text=case_text,
            case_name=case_name,
            citation=citation
        )
        return [TextContent(type="text", text=output)]

    else:
        return [TextContent(type="text", text=f"Unknown tool: {name}")]


# ============================================================================
# SERVER STARTUP
# ============================================================================

async def main():
    """Run the text-based MCP server."""
    async with stdio_server() as (read_stream, write_stream):
        await app.run(
            read_stream,
            write_stream,
            app.create_initialization_options()
        )

if __name__ == "__main__":
    asyncio.run(main())
